Tizen 2.1 base
authorJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:51:17 +0000 (01:51 +0900)
committerJinkun Jang <jinkun.jang@samsung.com>
Tue, 12 Mar 2013 16:51:17 +0000 (01:51 +0900)
121 files changed:
CMakeLists.txt
LICENSE.APLv2 [new file with mode: 0644]
NOTICE
calendar-service.manifest [new file with mode: 0644]
calendar.pc
client/CMakeLists.txt [new file with mode: 0755]
client/cal_client_alert.c [new file with mode: 0644]
client/cal_client_db.c [new file with mode: 0644]
client/cal_client_ipc.c [new file with mode: 0644]
client/cal_client_ipc.h [new file with mode: 0644]
client/calendar-service2.pc [new file with mode: 0755]
common/cal_filter.c [new file with mode: 0644]
common/cal_filter.h [new file with mode: 0644]
common/cal_inotify.c [new file with mode: 0644]
common/cal_inotify.h [new file with mode: 0644]
common/cal_internal.h [new file with mode: 0644]
common/cal_list.c [new file with mode: 0644]
common/cal_list.h [new file with mode: 0644]
common/cal_mutex.c [new file with mode: 0644]
common/cal_mutex.h [new file with mode: 0644]
common/cal_query.c [new file with mode: 0644]
common/cal_query.h [new file with mode: 0644]
common/cal_record.c [new file with mode: 0644]
common/cal_record.h [new file with mode: 0644]
common/cal_record_alarm.c [new file with mode: 0644]
common/cal_record_attendee.c [new file with mode: 0644]
common/cal_record_calendar.c [new file with mode: 0644]
common/cal_record_event.c [new file with mode: 0644]
common/cal_record_extended.c [new file with mode: 0644]
common/cal_record_instance_allday.c [new file with mode: 0644]
common/cal_record_instance_normal.c [new file with mode: 0644]
common/cal_record_search.c [new file with mode: 0644]
common/cal_record_timezone.c [new file with mode: 0644]
common/cal_record_todo.c [new file with mode: 0644]
common/cal_record_updated_info.c [new file with mode: 0644]
common/cal_time.cpp [new file with mode: 0644]
common/cal_time.h [new file with mode: 0644]
common/cal_typedef.h [new file with mode: 0755]
common/cal_vcalendar.c [new file with mode: 0644]
common/cal_vcalendar.h [new file with mode: 0644]
common/cal_vcalendar_make.c [new file with mode: 0644]
common/cal_vcalendar_make.h [new file with mode: 0644]
common/cal_vcalendar_parse.c [new file with mode: 0644]
common/cal_vcalendar_parse.h [new file with mode: 0644]
common/cal_view.c [new file with mode: 0644]
common/cal_view.h [new file with mode: 0644]
common/ipc/cal_ipc.h [new file with mode: 0644]
common/ipc/cal_ipc_marshal.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal.h [new file with mode: 0644]
common/ipc/cal_ipc_marshal_alarm.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_attendee.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_calendar.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_event.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_extended.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_instance_allday.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_instance_normal.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_search.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_timezone.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_todo.c [new file with mode: 0644]
common/ipc/cal_ipc_marshal_updated_info.c [new file with mode: 0644]
dft/CMakeLists.txt [new file with mode: 0644]
dft/src/dft_main.c [new file with mode: 0644]
dft/src/dft_util.c [new file with mode: 0644]
dft/src/dft_util.h [new file with mode: 0644]
include/calendar2.h [new file with mode: 0755]
include/calendar_db.h [new file with mode: 0644]
include/calendar_errors.h [new file with mode: 0644]
include/calendar_filter.h [new file with mode: 0644]
include/calendar_list.h [new file with mode: 0644]
include/calendar_query.h [new file with mode: 0644]
include/calendar_record.h [new file with mode: 0644]
include/calendar_reminder.h [new file with mode: 0644]
include/calendar_service.h [new file with mode: 0644]
include/calendar_types2.h [new file with mode: 0644]
include/calendar_vcalendar.h [new file with mode: 0644]
include/calendar_view.h [new file with mode: 0644]
native/CMakeLists.txt [new file with mode: 0755]
native/cal_calendar.c [new file with mode: 0644]
native/cal_db.c [new file with mode: 0644]
native/cal_db.h [new file with mode: 0644]
native/cal_db_alarm.c [new file with mode: 0644]
native/cal_db_alarm.h [new file with mode: 0644]
native/cal_db_attendee.c [new file with mode: 0644]
native/cal_db_attendee.h [new file with mode: 0644]
native/cal_db_extended.c [new file with mode: 0644]
native/cal_db_extended.h [new file with mode: 0644]
native/cal_db_instance.c [new file with mode: 0644]
native/cal_db_instance.h [new file with mode: 0644]
native/cal_db_plugin_calendar.c [new file with mode: 0644]
native/cal_db_plugin_event.c [new file with mode: 0644]
native/cal_db_plugin_extended.c [new file with mode: 0644]
native/cal_db_plugin_instance_allday.c [new file with mode: 0644]
native/cal_db_plugin_instance_normal.c [new file with mode: 0644]
native/cal_db_plugin_search.c [new file with mode: 0644]
native/cal_db_plugin_timezone.c [new file with mode: 0644]
native/cal_db_plugin_todo.c [new file with mode: 0644]
native/cal_db_query.c [new file with mode: 0644]
native/cal_db_query.h [new file with mode: 0644]
native/cal_db_rrule.c [new file with mode: 0644]
native/cal_db_rrule.h [new file with mode: 0644]
native/cal_db_util.c [new file with mode: 0644]
native/cal_db_util.h [new file with mode: 0644]
native/cal_reminder.c [new file with mode: 0644]
native/calendar-service-native.pc [new file with mode: 0755]
native/calendar-service2.pc [new file with mode: 0755]
packaging/calendar-service.spec [new file with mode: 0644]
packaging/calendar.service [new file with mode: 0644]
schema/CMakeLists.txt
schema/generator.sh
schema/header-gen/schema-header-gen.c
schema/initdb.c
schema/schema.sql
server/CMakeLists.txt [new file with mode: 0755]
server/cal_server.c [new file with mode: 0644]
server/cal_server_alarm.c [new file with mode: 0644]
server/cal_server_alarm.h [new file with mode: 0644]
server/cal_server_calendar_delete.c [new file with mode: 0644]
server/cal_server_calendar_delete.h [new file with mode: 0644]
server/cal_server_ipc.c [new file with mode: 0644]
server/cal_server_ipc.h [new file with mode: 0644]
server/calendar-serviced.sh [new file with mode: 0755]

index 93cf8d0..6e59d2e 100755 (executable)
@@ -1,5 +1,5 @@
 CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
-PROJECT(calendar-service C)
+PROJECT(calendar-service C CXX)
 
 #IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
 #      SET(CMAKE_BUILD_TYPE "Release")
@@ -14,15 +14,13 @@ SET(EXEC_PREFIX "\${prefix}")
 SET(LIBDIR "\${prefix}/lib")
 SET(INCLUDEDIR "\${prefix}/${DEST_INCLUDE_DIR}")
 SET(VERSION_MAJOR 0)
-SET(VERSION "${VERSION_MAJOR}.1.12")
+SET(VERSION "${VERSION_MAJOR}.1.14")
 
 #INCLUDE_DIRECTORIES(${SRC_INCLUDE_DIR})
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -I${CMAKE_SOURCE_DIR}/include")
 
-FILE(GLOB SRCS src/*.c)
-
 INCLUDE(FindPkgConfig)
-pkg_check_modules(pkgs REQUIRED glib-2.0 sqlite3 vconf dlog db-util alarm-service)
+pkg_check_modules(pkgs REQUIRED glib-2.0 sqlite3 vconf dlog db-util alarm-service icu-i18n appsvc)
 
 FOREACH(flag ${pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -31,34 +29,21 @@ ENDFOREACH(flag)
 SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
 
 SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
 #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})
-
-CONFIGURE_FILE(${PROJECT_NAME}.pc.in ${PROJECT_NAME}.pc @ONLY)
-SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${PROJECT_NAME}.pc;schema/schema.h")
-
-INSTALL(TARGETS ${PROJECT_NAME} DESTINATION lib)
-INSTALL(FILES ${PROJECT_NAME}.pc DESTINATION lib/pkgconfig)
-
-FILE(GLOB HEADER_FILES ${SRC_INCLUDE_DIR}/calendar-svc*.h)
-INSTALL(FILES ${HEADER_FILES} DESTINATION ${DEST_INCLUDE_DIR})
-
-FILE(GLOB NOTI_FILES ${CMAKE_SOURCE_DIR}/.CALENDAR_SVC_*_CHANGED)
-INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/data/calendar-svc)
-
 # for immigration
 SET(IMMIGRATION "calendar")
-SET(OLD_DEST_INCLUDE_DIR "include/calendar")
 INSTALL(FILES ${IMMIGRATION}.pc DESTINATION lib/pkgconfig)
-INSTALL(FILES ${SRC_INCLUDE_DIR}/calendar-svc-provider.h DESTINATION ${OLD_DEST_INCLUDE_DIR})
-INSTALL(FILES ${SRC_INCLUDE_DIR}/calendar-svc-struct.h DESTINATION ${OLD_DEST_INCLUDE_DIR})
-INSTALL(FILES ${SRC_INCLUDE_DIR}/calendar-svc-errors.h DESTINATION ${OLD_DEST_INCLUDE_DIR})
+
+FILE(GLOB NOTI_FILES ${CMAKE_SOURCE_DIR}/.CALENDAR_SVC_*_CHANGED)
+INSTALL(FILES ${NOTI_FILES} DESTINATION /opt/usr/data/calendar-svc)
 
 ADD_SUBDIRECTORY(schema)
+ADD_SUBDIRECTORY(client)
+ADD_SUBDIRECTORY(server)
+ADD_SUBDIRECTORY(native)
+ADD_SUBDIRECTORY(dft)
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..311e5ba
--- /dev/null
@@ -0,0 +1,204 @@
+Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
diff --git a/NOTICE b/NOTICE
index 4c49449..d34af37 100644 (file)
--- a/NOTICE
+++ b/NOTICE
@@ -1 +1 @@
-Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
diff --git a/calendar-service.manifest b/calendar-service.manifest
new file mode 100644 (file)
index 0000000..8d0fe82
--- /dev/null
@@ -0,0 +1,23 @@
+<manifest>
+       <define>
+               <domain name="calendar-service"/>
+               <provide>
+                       <label name="calendar-service::initdb" />
+                       <label name="calendar-service::db" />
+               </provide>
+       </define>
+       <assign>
+               <filesystem path="/usr/lib/libcalendar-service2.so.0.1.14" label="_" />
+               <filesystem path="/usr/lib/libcalendar-service2.so.0" label="_" />
+               <filesystem path="/usr/lib/libcalendar-service2.so" label="_" />
+               <filesystem path="/usr/lib/libcalendar-service-native.so.0.1.14" label="_" />
+               <filesystem path="/usr/lib/libcalendar-service-native.so.0" label="_" />
+               <filesystem path="/usr/lib/libcalendar-service-native.so" label="_" />
+               <filesystem path="/etc/rc.d/init.d/calendar-serviced.sh" label="_" exec_label="none" />
+               <filesystem path="/etc/rc.d/rc3.d/S85calendar-serviced" label="_" exec_label="none" />
+               <filesystem path="/etc/rc.d/rc5.d/S85calendar-serviced" label="_" exec_label="none" />
+       </assign>
+       <request>
+               <domain name="calendar-service" />
+       </request>
+</manifest>
index 2b4d600..65f36aa 100755 (executable)
@@ -3,11 +3,11 @@
 prefix=/usr
 exec_prefix=${prefix}
 libdir=${prefix}/lib
-includedir=${prefix}/include/calendar-svc
+includedir=${prefix}/include/calendar-service2
 
-Name: calendar-service
-Description: calendar-service library
+Name: calendar-service2
+Description: calendar-service2 library
 Version: 0.1.8
 Requires: glib-2.0 alarm-service
-Libs: -L${libdir} -lcalendar-service
+Libs: -L${libdir} -lcalendar-service2
 Cflags: -I${includedir}
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..9a81f5c
--- /dev/null
@@ -0,0 +1,78 @@
+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)
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+
+SET(INC_DIR ${CMAKE_SOURCE_DIR}/include)
+
+SET(CALSVC2 calendar-service2)
+
+SET(SRCS
+       cal_client_ipc.c
+       cal_client_db.c
+    cal_client_alert.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_alarm.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_attendee.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_calendar.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_event.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_instance_allday.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_instance_normal.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_search.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_timezone.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_todo.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_updated_info.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_extended.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_calendar.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_event.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_todo.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_attendee.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_alarm.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_search.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_timezone.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_updated_info.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_instance_normal.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_instance_allday.c
+    ${CMAKE_SOURCE_DIR}/common/cal_record_extended.c
+    ${CMAKE_SOURCE_DIR}/common/cal_view.c
+    ${CMAKE_SOURCE_DIR}/common/cal_filter.c
+    ${CMAKE_SOURCE_DIR}/common/cal_query.c
+    ${CMAKE_SOURCE_DIR}/common/cal_inotify.c
+    ${CMAKE_SOURCE_DIR}/common/cal_list.c
+    ${CMAKE_SOURCE_DIR}/common/cal_time.cpp
+    ${CMAKE_SOURCE_DIR}/common/cal_vcalendar.c
+    ${CMAKE_SOURCE_DIR}/common/cal_vcalendar_make.c
+    ${CMAKE_SOURCE_DIR}/common/cal_vcalendar_parse.c
+    ${CMAKE_SOURCE_DIR}/common/cal_mutex.c
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(service2_pkgs REQUIRED pims-ipc dlog capi-base-common)
+
+FOREACH(flag ${service2_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+SET(service2_pkgs_LDFLAGS "${pkgs_LDFLAGS} ${service2_pkgs_LDFLAGS}")
+
+ADD_DEFINITIONS("-DCAL_IPC_CLIENT")
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_LIBRARY(${CALSVC2} SHARED ${SRCS})
+SET_TARGET_PROPERTIES(${CALSVC2} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${CALSVC2} PROPERTIES VERSION ${VERSION})
+TARGET_LINK_LIBRARIES(${CALSVC2} ${service2_pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${CALSVC2} DESTINATION lib)
+INSTALL(FILES ${CALSVC2}.pc DESTINATION lib/pkgconfig)
+
+#header
+FILE(GLOB HEADER_FILES ${INC_DIR}/calendar*.h)
+INSTALL(FILES ${HEADER_FILES} DESTINATION include/calendar-service2)
diff --git a/client/cal_client_alert.c b/client/cal_client_alert.c
new file mode 100644 (file)
index 0000000..5e35c81
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <pims-ipc.h>
+
+#include "calendar_service.h"
+#include "calendar_db.h"
+#include "calendar_types2.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_inotify.h"
+#include "cal_view.h"
+#include "cal_record.h"
+#include "cal_list.h"
+#include "cal_mutex.h"
+
+#include "cal_ipc.h"
+#include "cal_ipc_marshal.h"
+
+#include "cal_client_ipc.h"
+
+#define CAL_IPC_DATA_FREE(ptr) \
+    do { \
+        if (ptr) \
+        pims_ipc_data_destroy(ptr); \
+        ptr = NULL; \
+    } while(0)
+
+API int calendar_reminder_add_receiver(const char *pkgname, const char *extra_data_key, const char *extra_data_value)
+{
+       int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+       retvm_if(NULL == pkgname, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       // make data
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(pkgname, indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(extra_data_key, indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(extra_data_value, indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+       // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REGISTER_REMINDER, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+    CAL_IPC_DATA_FREE(indata);
+
+       if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_reminder_remove_receiver(const char *pkgname)
+{
+       int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+       retvm_if(NULL == pkgname, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       // make data
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(pkgname, indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+       // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_UNREGISTER_REMINDER, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+    CAL_IPC_DATA_FREE(indata);
+
+       if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_reminder_activate_receiver(const char *pkgname)
+{
+       int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+       retvm_if(NULL == pkgname, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       // make data
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(pkgname, indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+       // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_ACTIVATE_REMINDER, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+    CAL_IPC_DATA_FREE(indata);
+
+       if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_reminder_deactivate_receiver(const char *pkgname)
+{
+       int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+       retvm_if(NULL == pkgname, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       // make data
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(pkgname, indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+       // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_DEACTIVATE_REMINDER, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+    CAL_IPC_DATA_FREE(indata);
+
+       if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_reminder_has_receiver(const char *pkgname)
+{
+       int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+       retvm_if(NULL == pkgname, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       // make data
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(pkgname, indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+       // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_HAS_REMINDER, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+    CAL_IPC_DATA_FREE(indata);
+
+       if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
diff --git a/client/cal_client_db.c b/client/cal_client_db.c
new file mode 100644 (file)
index 0000000..281b49b
--- /dev/null
@@ -0,0 +1,2011 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <pims-ipc.h>
+#include <glib-object.h>    //g_type_init
+
+#include "calendar_service.h"
+#include "calendar_db.h"
+#include "calendar_types2.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_inotify.h"
+#include "cal_view.h"
+#include "cal_record.h"
+#include "cal_list.h"
+#include "cal_mutex.h"
+
+#include "cal_ipc.h"
+#include "cal_ipc_marshal.h"
+
+#include "cal_client_ipc.h"
+
+typedef struct {
+    calendar_db_result_cb callback;
+    void *user_data;
+}cal_client_db_async_userdata_s;
+
+typedef struct {
+    calendar_db_insert_result_cb callback;
+    void *user_data;
+}cal_client_db_async_insert_userdata_s;
+
+#define CAL_IPC_DATA_FREE(ptr) \
+    do { \
+        if (ptr) \
+        pims_ipc_data_destroy(ptr); \
+        ptr = NULL; \
+    } while(0)
+
+
+void __cal_client_db_insert_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+void __cal_client_db_update_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+void __cal_client_db_delete_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+void __cal_client_db_insert_vcalendars_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+void __cal_client_db_replace_vcalendars_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+void __cal_client_db_replace_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata);
+
+void __cal_client_db_insert_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+    cal_client_db_async_insert_userdata_s *sync_data = (cal_client_db_async_insert_userdata_s *)userdata;
+    int ret = CALENDAR_ERROR_NONE;
+
+    int count = 0;
+    int *id = 0;
+
+    if (sync_data == NULL)
+    {
+        ERR("sync_data is NULL");
+        return;
+    }
+
+    if (data_out)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(data_out,&size);
+
+        if (ret == CALENDAR_ERROR_NONE )
+        {
+            int i=0;
+            unsigned int size = 0;
+
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(data_out,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+
+            count = *(int*) pims_ipc_data_get(data_out,&size);
+
+            id = calloc(1, sizeof(int)*count);
+
+            if (id)
+            {
+                for(i=0;i<count;i++)
+                {
+                    id[i] = *(unsigned int*) pims_ipc_data_get(data_out,&size);
+                }
+            }
+            else
+            {
+                count = 0;
+            }
+        }
+
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_IPC;
+        ERR("async cb is no data");
+    }
+
+    if (sync_data->callback)
+    {
+        sync_data->callback(ret, id, count, sync_data->user_data);
+    }
+
+       _cal_inotify_call_pending_callback();
+
+    CAL_FREE(id);
+
+    CAL_FREE(sync_data);
+
+    return ;
+}
+
+void __cal_client_db_update_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+    cal_client_db_async_userdata_s *sync_data = (cal_client_db_async_userdata_s *)userdata;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (sync_data == NULL)
+    {
+        ERR("sync_data is NULL");
+        return;
+    }
+
+    if (data_out)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(data_out,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(data_out,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_IPC;
+        ERR("async cb is no data");
+    }
+
+    if (sync_data->callback)
+    {
+        sync_data->callback(ret, sync_data->user_data);
+    }
+
+       _cal_inotify_call_pending_callback();
+
+    CAL_FREE(sync_data);
+
+    return ;
+}
+void __cal_client_db_delete_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+    cal_client_db_async_userdata_s *sync_data = (cal_client_db_async_userdata_s *)userdata;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (sync_data == NULL)
+    {
+        ERR("sync_data is NULL");
+        return;
+    }
+
+    if (data_out)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(data_out,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(data_out,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_IPC;
+        ERR("async cb is no data");
+    }
+
+    if (sync_data->callback)
+    {
+        sync_data->callback(ret, sync_data->user_data);
+    }
+
+       _cal_inotify_call_pending_callback();
+
+    CAL_FREE(sync_data);
+
+    return ;
+}
+
+void __cal_client_db_insert_vcalendars_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+    cal_client_db_async_insert_userdata_s *sync_data = (cal_client_db_async_insert_userdata_s *)userdata;
+    int ret = CALENDAR_ERROR_NONE;
+
+    int count = 0;
+    int *id = 0;
+
+    if (sync_data == NULL)
+    {
+        ERR("sync_data is NULL");
+        return;
+    }
+
+    if (data_out)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(data_out,&size);
+
+        if (ret == CALENDAR_ERROR_NONE )
+        {
+            int i=0;
+            unsigned int size = 0;
+
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(data_out,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+
+            count = *(int*) pims_ipc_data_get(data_out,&size);
+
+            id = calloc(1, sizeof(int)*count);
+
+            if (id)
+            {
+                for(i=0;i<count;i++)
+                {
+                    id[i] = *(unsigned int*) pims_ipc_data_get(data_out,&size);
+                }
+            }
+            else
+            {
+                count = 0;
+            }
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_IPC;
+        ERR("async cb is no data");
+    }
+
+    if (sync_data->callback)
+    {
+        sync_data->callback(ret, id, count, sync_data->user_data);
+    }
+
+    _cal_inotify_call_pending_callback();
+
+    CAL_FREE(id);
+
+    CAL_FREE(sync_data);
+
+    return ;
+}
+
+void __cal_client_db_replace_vcalendars_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+    cal_client_db_async_userdata_s *sync_data = (cal_client_db_async_userdata_s *)userdata;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (sync_data == NULL)
+    {
+        ERR("sync_data is NULL");
+        return;
+    }
+
+    if (data_out)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(data_out,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(data_out,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_IPC;
+        ERR("async cb is no data");
+    }
+
+    if (sync_data->callback)
+    {
+        sync_data->callback(ret, sync_data->user_data);
+    }
+
+    _cal_inotify_call_pending_callback();
+
+    CAL_FREE(sync_data);
+
+    return ;
+}
+
+void __cal_client_db_replace_records_cb(pims_ipc_h ipc, pims_ipc_data_h data_out, void *userdata)
+{
+    cal_client_db_async_userdata_s *sync_data = (cal_client_db_async_userdata_s *)userdata;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (sync_data == NULL)
+    {
+        ERR("sync_data is NULL");
+        return;
+    }
+
+    if (data_out)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(data_out,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(data_out,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_IPC;
+        ERR("async cb is no data");
+    }
+
+    if (sync_data->callback)
+    {
+        sync_data->callback(ret, sync_data->user_data);
+    }
+
+    _cal_inotify_call_pending_callback();
+
+    CAL_FREE(sync_data);
+
+    return ;
+}
+
+API int calendar_db_insert_record( calendar_record_h record, int* id )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(record==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_record(record,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_INSERT_RECORD, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        //int id = 0;
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+            //unsigned int property_id = 0;
+            int out_id = 0;
+            //property_id = *(unsigned int*)pims_ipc_data_get(outdata,&size);
+            out_id = *(int*)pims_ipc_data_get(outdata,&size);
+            //_cal_record_set_int(record,property_id,id);
+            if (id)
+            {
+                *id = out_id;
+            }
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_get_record( const char* view_uri, int id, calendar_record_h* out_record )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(view_uri==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+    retvm_if(id<=0,CALENDAR_ERROR_INVALID_PARAMETER,"id <= 0");
+    retvm_if(out_record==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(view_uri,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(id,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_RECORD, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            ret = _cal_ipc_unmarshal_record(outdata,out_record);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_update_record( calendar_record_h record )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(record==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_record(record,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_UPDATE_RECORD, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_delete_record( const char* view_uri, int id )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(view_uri==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+    retvm_if(id<=0,CALENDAR_ERROR_INVALID_PARAMETER,"id <= 0");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(view_uri,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(id,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_DELETE_RECORD, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_get_all_records( const char* view_uri, int offset, int limit, calendar_list_h* out_list )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(out_list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"list is NULL");
+    retvm_if(view_uri==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+
+    ret = _cal_ipc_marshal_char(view_uri,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(offset,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(limit,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_ALL_RECORDS, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            ret = _cal_ipc_unmarshal_list(outdata,out_list);
+        }
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(query==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"query is NULL");
+    retvm_if(out_list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"list is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_query(query,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(offset,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(limit,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_RECORDS_WITH_QUERY, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            ret = _cal_ipc_unmarshal_list(outdata,out_list);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_clean_after_sync( int calendar_book_id )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(calendar_book_id <= 0,CALENDAR_ERROR_INVALID_PARAMETER,"calendar_book_id < 0");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(calendar_book_id,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_CLEAN_AFTER_SYNC, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_get_count( const char* view_uri, int *out_count )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(view_uri==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+    retvm_if(out_count==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"count pointer is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(view_uri,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_COUNT, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            ret = _cal_ipc_unmarshal_int(outdata,out_count);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_get_count_with_query( calendar_query_h query, int *out_count )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(query==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_query(query,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_COUNT_WITH_QUERY, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            ret = _cal_ipc_unmarshal_int(outdata,out_count);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_insert_records( calendar_list_h record_list, int** record_id_array, int* count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(record_list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"list is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_list(record_list,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    if (_cal_client_ipc_call(CAL_IPC_MODULE,CAL_IPC_SERVER_DB_INSERT_RECORDS,
+            indata,&outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+            goto SET_DATA;
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+
+SET_DATA:
+    if (outdata)
+    {
+        int i=0;
+        unsigned int size = 0;
+        int *ids = NULL;
+
+        if (count && record_id_array)
+        {
+            *count = *(int*) pims_ipc_data_get(outdata,&size);
+
+            if (*count <=0)
+            {
+                ERR("count is %d",*count);
+                count = 0;
+                pims_ipc_data_destroy(outdata);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            ids = calloc(1, sizeof(int)*(*count));
+
+            if(ids == NULL)
+            {
+                count = 0;
+                ERR("calloc fail");
+                pims_ipc_data_destroy(outdata);
+                return CALENDAR_ERROR_OUT_OF_MEMORY;
+            }
+            for(i=0;i<(*count);i++)
+            {
+                ids[i] = *(int*) pims_ipc_data_get(outdata,&size);
+            }
+            *record_id_array = ids;
+        }
+        pims_ipc_data_destroy(outdata);
+    }
+
+    return ret;
+}
+
+API int calendar_db_insert_records_async(calendar_list_h list, calendar_db_insert_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    cal_client_db_async_insert_userdata_s *async_data = NULL;
+    calendar_list_h clone_list = NULL;
+
+    retvm_if(list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"list is NULL");
+    retvm_if(callback==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"list is NULL");
+
+    ret = _cal_list_clone(list, &clone_list);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_list_clone() failed");
+               return ret;
+       }
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        calendar_list_destroy(clone_list, true);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_list(clone_list,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        calendar_list_destroy(clone_list, true);
+        return ret;
+    }
+
+    async_data = (cal_client_db_async_insert_userdata_s*)malloc(sizeof(cal_client_db_async_insert_userdata_s));
+    if (async_data == NULL)
+    {
+        ERR("malloc fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        calendar_list_destroy(clone_list, true);
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    async_data->callback = callback;
+    async_data->user_data = user_data;
+
+    if (_cal_client_ipc_call_async(CAL_IPC_MODULE,CAL_IPC_SERVER_DB_INSERT_RECORDS,
+            indata,__cal_client_db_insert_records_cb,async_data) != 0)
+    {
+        ERR("pims_ipc_call_async failed");
+        calendar_list_destroy(clone_list, true);
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    calendar_list_destroy(clone_list, true);
+
+    return ret;
+}
+
+API int calendar_db_update_records( calendar_list_h record_list)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(record_list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_list(record_list,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_UPDATE_RECORDS, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+
+}
+
+API int calendar_db_update_records_async( calendar_list_h list, calendar_db_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    cal_client_db_async_userdata_s *async_data = NULL;
+    calendar_list_h clone_list = NULL;
+
+    retvm_if(list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+    retvm_if(callback==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"callback is NULL");
+
+    ret = _cal_list_clone(list, &clone_list);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_list_clone() failed");
+               return ret;
+       }
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        calendar_list_destroy(clone_list, true);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_list(clone_list,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        calendar_list_destroy(clone_list, true);
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    async_data = (cal_client_db_async_userdata_s*)malloc(sizeof(cal_client_db_async_userdata_s));
+    if (async_data == NULL)
+    {
+        ERR("malloc fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        calendar_list_destroy(clone_list, true);
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    async_data->callback = callback;
+    async_data->user_data = user_data;
+
+    if (_cal_client_ipc_call_async(CAL_IPC_MODULE,CAL_IPC_SERVER_DB_UPDATE_RECORDS,
+            indata,__cal_client_db_update_records_cb,async_data) != 0)
+    {
+        ERR("pims_ipc_call_async failed");
+        calendar_list_destroy(clone_list, true);
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    calendar_list_destroy(clone_list, true);
+    return ret;
+}
+
+API int calendar_db_delete_records(const char* view_uri, int record_id_array[], int count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+    int i = 0;
+
+    retvm_if(view_uri==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+    retvm_if(record_id_array==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record_id_array is NULL");
+    retvm_if(count<=0,CALENDAR_ERROR_INVALID_PARAMETER,"count <= 0 ");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(view_uri,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(count,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    for (i=0;i<count;i++)
+    {
+        ret = _cal_ipc_marshal_int(record_id_array[i],indata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("marshal fail");
+            CAL_IPC_DATA_FREE(indata);
+            return ret;
+        }
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_DELETE_RECORDS, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+
+}
+
+API int calendar_db_delete_records_async(const char* view_uri, int ids[], int count, calendar_db_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    int i = 0;
+    cal_client_db_async_userdata_s *async_data = NULL;
+
+    retvm_if(view_uri==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+    retvm_if(callback==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"callback is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(view_uri,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(count,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    for (i=0;i<count;i++)
+    {
+        ret = _cal_ipc_marshal_int(ids[i],indata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("marshal fail");
+            CAL_IPC_DATA_FREE(indata);
+            return ret;
+        }
+    }
+
+    async_data = (cal_client_db_async_userdata_s*)malloc(sizeof(cal_client_db_async_userdata_s));
+    if (async_data == NULL)
+    {
+        ERR("malloc fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    async_data->callback = callback;
+    async_data->user_data = user_data;
+    if (_cal_client_ipc_call_async(CAL_IPC_MODULE,CAL_IPC_SERVER_DB_DELETE_RECORDS,
+            indata,__cal_client_db_delete_records_cb,async_data) != 0)
+    {
+        ERR("pims_ipc_call_async failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    return ret;
+}
+
+API int calendar_db_get_changes_by_version(const char* view_uri, int calendar_book_id, int calendar_db_version, calendar_list_h* record_list, int* current_calendar_db_version )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(view_uri==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"view_uri is NULL");
+    retvm_if(record_list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record_list is NULL");
+    retvm_if(current_calendar_db_version==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"current_calendar_db_version is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(view_uri,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(calendar_book_id,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(calendar_db_version,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_CHANGES_BY_VERSION, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            ret = _cal_ipc_unmarshal_list(outdata,record_list);
+
+            if (ret == CALENDAR_ERROR_NONE)
+            {
+                ret = _cal_ipc_unmarshal_int(outdata,current_calendar_db_version);
+            }
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_get_current_version(int* calendar_db_version)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(calendar_db_version==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"calendar_db_version is null");
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_CURRENT_VERSION, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            ret = _cal_ipc_unmarshal_int(outdata,calendar_db_version);
+        }
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_add_changed_cb(const char* view_uri, calendar_db_changed_cb callback, void* user_data )
+{
+    CAL_FN_CALL;
+    int ret;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    retv_if(NULL == view_uri || NULL == callback , CALENDAR_ERROR_INVALID_PARAMETER);
+
+    type = _cal_view_get_type(view_uri);
+
+    switch(type)
+    {
+    case CAL_RECORD_TYPE_CALENDAR:
+        ret = _cal_inotify_subscribe(CAL_NOTI_TYPE_CALENDAR, CAL_NOTI_CALENDAR_CHANGED, callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_EVENT:
+        ret = _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_TODO:
+        ret = _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, user_data);
+        break;
+    default:
+        ERR("Invalid view_uri(%s)", view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    retvm_if(CALENDAR_ERROR_NONE != ret, ret, "_cal_inotify_subscribe() Failed(%d)", ret);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_remove_changed_cb( const char* view_uri, calendar_db_changed_cb callback, void* user_data )
+{
+    CAL_FN_CALL;
+    int ret;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    retv_if(NULL == view_uri || NULL == callback , CALENDAR_ERROR_INVALID_PARAMETER);
+
+    type = _cal_view_get_type(view_uri);
+
+    switch(type)
+    {
+    case CAL_RECORD_TYPE_CALENDAR:
+        ret = _cal_inotify_unsubscribe_with_data(CAL_NOTI_CALENDAR_CHANGED, callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_EVENT:
+        ret = _cal_inotify_unsubscribe_with_data(CAL_NOTI_EVENT_CHANGED, callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_TODO:
+        ret = _cal_inotify_unsubscribe_with_data(CAL_NOTI_TODO_CHANGED, callback, user_data);
+        break;
+    default:
+        ERR("Invalid view_uri(%s)", view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    retvm_if(CALENDAR_ERROR_NONE != ret, ret, "_cal_inotify_unsubscribe_with_data() Failed(%d)", ret);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_insert_vcalendars(const char* vcalendar_stream, int **record_id_array, int *count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+    int i = 0;
+
+    retvm_if(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(vcalendar_stream,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_INSERT_VCALENDARS, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+    CAL_IPC_DATA_FREE(indata);
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+
+        if (ret == CALENDAR_ERROR_NONE && count != NULL && record_id_array != NULL)
+        {
+            int *ids = NULL;
+
+            *count = *(int*) pims_ipc_data_get(outdata,&size);
+
+            ids = (int*)malloc(sizeof(int)*(*count));
+            if(ids == NULL)
+            {
+                pims_ipc_data_destroy(outdata);
+                ERR("malloc fail");
+                return CALENDAR_ERROR_OUT_OF_MEMORY;
+            }
+            for(i=0;i<(*count);i++)
+            {
+                ids[i] = *(int*) pims_ipc_data_get(outdata,&size);
+            }
+
+            *record_id_array = ids;
+        }
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_insert_vcalendars_async(const char* vcalendar_stream, calendar_db_insert_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    cal_client_db_async_insert_userdata_s *async_data = NULL;
+
+    retvm_if(vcalendar_stream==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"list is NULL");
+    retvm_if(callback==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"list is NULL");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(vcalendar_stream,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+
+        return ret;
+    }
+
+    async_data = (cal_client_db_async_insert_userdata_s*)malloc(sizeof(cal_client_db_async_insert_userdata_s));
+    if (async_data == NULL)
+    {
+        ERR("malloc fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    async_data->callback = callback;
+    async_data->user_data = user_data;
+
+    if (_cal_client_ipc_call_async(CAL_IPC_MODULE,CAL_IPC_SERVER_DB_INSERT_VCALENDARS,
+            indata,__cal_client_db_insert_vcalendars_cb,async_data) != 0)
+    {
+        ERR("pims_ipc_call_async failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    return ret;
+}
+
+API int calendar_db_replace_vcalendars(const char* vcalendar_stream, int *record_id_array, int count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+    int i = 0;
+
+    retvm_if(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(vcalendar_stream,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(count,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    for(i=0;i<count;i++)
+    {
+        ret = _cal_ipc_marshal_int(record_id_array[i],indata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("marshal fail");
+            CAL_IPC_DATA_FREE(indata);
+            return ret;
+        }
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REPLACE_VCALENDARS, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+    CAL_IPC_DATA_FREE(indata);
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_replace_vcalendars_async(const char* vcalendar_stream, int *record_id_array, int count, calendar_db_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    cal_client_db_async_userdata_s *async_data = NULL;
+    int i = 0;
+
+    retvm_if(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_char(vcalendar_stream,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(count,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    for(i=0;i<count;i++)
+    {
+        ret = _cal_ipc_marshal_int(record_id_array[i],indata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("marshal fail");
+            CAL_IPC_DATA_FREE(indata);
+            return ret;
+        }
+    }
+
+    async_data = (cal_client_db_async_userdata_s*)malloc(sizeof(cal_client_db_async_userdata_s));
+    if (async_data == NULL)
+    {
+        ERR("malloc fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    async_data->callback = callback;
+    async_data->user_data = user_data;
+
+    if (_cal_client_ipc_call_async(CAL_IPC_MODULE,CAL_IPC_SERVER_DB_REPLACE_VCALENDARS,
+            indata,__cal_client_db_replace_vcalendars_cb,async_data) != 0)
+    {
+        ERR("pims_ipc_call_async failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    return ret;
+}
+
+API int calendar_db_replace_record(calendar_record_h record, int record_id)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(record==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+    retvm_if(record_id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_record(record,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(record_id,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REPLACE_RECORD, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_replace_records(calendar_list_h record_list, int *record_id_array, int count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+    int i = 0;
+
+    retvm_if(record_list==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record is NULL");
+    retvm_if(record_id_array==NULL,CALENDAR_ERROR_INVALID_PARAMETER,"record_id_array is NULL");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_list(record_list,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(count,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    for(i=0;i<count;i++)
+    {
+        ret = _cal_ipc_marshal_int(record_id_array[i],indata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("marshal fail");
+            CAL_IPC_DATA_FREE(indata);
+            return ret;
+        }
+    }
+
+    // ipc call
+    if (_cal_client_ipc_call( CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REPLACE_RECORDS, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = 0;
+            transaction_ver = *(int*)pims_ipc_data_get(outdata,&size);
+            _cal_client_ipc_set_change_version(transaction_ver);
+        }
+        pims_ipc_data_destroy(outdata);
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        return CALENDAR_ERROR_IPC;
+    }
+
+    return ret;
+}
+
+API int calendar_db_replace_records_async(calendar_list_h record_list, int *record_id_array, int count, calendar_db_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    cal_client_db_async_userdata_s *async_data = NULL;
+    int i = 0;
+
+    retvm_if(NULL == record_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    // make indata
+    indata = pims_ipc_data_create(0);
+    if (indata == NULL)
+    {
+        ERR("ipc data created fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        return ret;
+    }
+    ret = _cal_ipc_marshal_list(record_list,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    ret = _cal_ipc_marshal_int(count,indata);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("marshal fail");
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    for(i=0;i<count;i++)
+    {
+        ret = _cal_ipc_marshal_int(record_id_array[i],indata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("marshal fail");
+            CAL_IPC_DATA_FREE(indata);
+            return ret;
+        }
+    }
+
+    async_data = (cal_client_db_async_userdata_s*)malloc(sizeof(cal_client_db_async_userdata_s));
+    if (async_data == NULL)
+    {
+        ERR("malloc fail !");
+        ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        CAL_IPC_DATA_FREE(indata);
+        return ret;
+    }
+    async_data->callback = callback;
+    async_data->user_data = user_data;
+
+    if (_cal_client_ipc_call_async(CAL_IPC_MODULE,CAL_IPC_SERVER_DB_REPLACE_RECORDS,
+            indata,__cal_client_db_replace_records_cb,async_data) != 0)
+    {
+        ERR("pims_ipc_call_async failed");
+        CAL_IPC_DATA_FREE(indata);
+        return CALENDAR_ERROR_IPC;
+    }
+
+    CAL_IPC_DATA_FREE(indata);
+
+    return ret;
+}
+
+API int calendar_db_get_last_change_version(int* last_version)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    retvm_if(NULL == last_version, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    *last_version = _cal_client_ipc_get_change_version();
+    return ret;
+}
diff --git a/client/cal_client_ipc.c b/client/cal_client_ipc.c
new file mode 100644 (file)
index 0000000..1e4f6f1
--- /dev/null
@@ -0,0 +1,426 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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>     //calloc
+#include <pims-ipc.h>
+#include <glib-object.h> //g_type_init
+
+#include "calendar_service.h"
+#include "calendar_db.h"
+#include "calendar_types2.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_inotify.h"
+#include "cal_view.h"
+#include "cal_record.h"
+#include "cal_list.h"
+#include "cal_mutex.h"
+
+#include "cal_ipc.h"
+#include "cal_ipc_marshal.h"
+
+#include "cal_client_ipc.h"
+
+static TLS pims_ipc_h calendar_ipc_thread = NULL;
+static pims_ipc_h calendar_ipc = NULL;
+static int calendar_connection_count = 0;
+static int calendar_change_version = 0;
+static TLS int calendar_change_version_thread = 0;
+
+pims_ipc_h __cal_client_ipc_get_handle(void);
+void __cal_client_ipc_lock(void);
+void __cal_client_ipc_unlock(void);
+
+API int calendar_connect(void)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+    pims_ipc_h ipc_handle = NULL;
+
+    CAL_FN_CALL;
+
+    _cal_mutex_lock(CAL_MUTEX_CONNECTION);
+    // ipc create
+    if (calendar_ipc == NULL)
+    {
+        ipc_handle = pims_ipc_create(CAL_IPC_SOCKET_PATH);
+        if (ipc_handle == NULL)
+        {
+            ERR("pims_ipc_create() Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        calendar_connection_count++;
+        CAL_DBG("calendar already connected = %d",calendar_connection_count);
+        ret = CALENDAR_ERROR_NONE;
+        _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
+        return ret;
+    }
+
+    // ipc call
+    if (pims_ipc_call(ipc_handle, CAL_IPC_MODULE, CAL_IPC_SERVER_CONNECT, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        ret = CALENDAR_ERROR_IPC;
+        goto ERROR_RETURN;
+    }
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_connect return (%d)",ret);
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        ret = CALENDAR_ERROR_IPC;
+        goto ERROR_RETURN;
+    }
+
+    g_type_init();  // added for alarmmgr
+
+    if (_cal_inotify_initialize() !=  CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_inotify_initialize failed");
+    }
+
+    _cal_view_initialize();
+
+    calendar_connection_count++;
+    calendar_ipc = ipc_handle;
+    _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
+
+       return ret;
+
+ERROR_RETURN:
+    if (ipc_handle != NULL)
+    {
+        pims_ipc_destroy(ipc_handle);
+        ipc_handle = NULL;
+    }
+       _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
+       return ret;
+}
+
+API int calendar_disconnect(void)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(calendar_ipc==NULL,CALENDAR_ERROR_NOT_PERMITTED,"calendar not connected");
+
+    CAL_FN_CALL;
+    _cal_mutex_lock(CAL_MUTEX_CONNECTION);
+
+    if (calendar_connection_count > 1)
+    {
+        calendar_connection_count--;
+        CAL_DBG("calendar connect count -1 = %d",calendar_connection_count);
+        ret = CALENDAR_ERROR_NONE;
+        _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
+        return ret;
+    }
+
+    // ipc call
+    if (pims_ipc_call(calendar_ipc, CAL_IPC_MODULE, CAL_IPC_SERVER_DISCONNECT, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        ret = CALENDAR_ERROR_NOT_PERMITTED;
+        goto ERROR_RETURN;
+    }
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        ret = CALENDAR_ERROR_IPC;
+        goto ERROR_RETURN;
+    }
+
+    if (calendar_ipc && ret == CALENDAR_ERROR_NONE)
+    {
+        pims_ipc_destroy(calendar_ipc);
+        calendar_ipc = NULL;
+
+        _cal_inotify_finalize();
+        _cal_view_finalize();
+    }
+
+    _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
+    return ret;
+ERROR_RETURN:
+
+    _cal_mutex_unlock(CAL_MUTEX_CONNECTION);
+    return ret;
+}
+
+API int calendar_connect_on_thread(void)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    CAL_FN_CALL;
+
+    // ipc create
+    if (calendar_ipc_thread == NULL)
+    {
+        calendar_ipc_thread = pims_ipc_create(CAL_IPC_SOCKET_PATH);
+        if (calendar_ipc_thread == NULL)
+        {
+            ERR("pims_ipc_create() Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        CAL_DBG("calendar already connected");
+        ret = CALENDAR_ERROR_NONE;
+        goto ERROR_RETURN;
+    }
+
+    // ipc call
+    if (pims_ipc_call(calendar_ipc_thread, CAL_IPC_MODULE, CAL_IPC_SERVER_CONNECT, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        ret = CALENDAR_ERROR_IPC;
+        goto ERROR_RETURN;
+    }
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_connect return (%d)",ret);
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        ret = CALENDAR_ERROR_IPC;
+        goto ERROR_RETURN;
+    }
+
+    if (_cal_inotify_initialize() !=  CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_inotify_initialize failed");
+    }
+
+    _cal_view_initialize();
+    return ret;
+
+ERROR_RETURN:
+    if (calendar_ipc_thread != NULL)
+    {
+        pims_ipc_destroy(calendar_ipc_thread);
+        calendar_ipc_thread = NULL;
+    }
+
+    return ret;
+}
+
+API int calendar_disconnect_on_thread(void)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    pims_ipc_data_h indata = NULL;
+    pims_ipc_data_h outdata = NULL;
+
+    retvm_if(calendar_ipc_thread==NULL,CALENDAR_ERROR_NOT_PERMITTED,"calendar_thread not connected");
+
+    CAL_FN_CALL;
+
+    // ipc call
+    if (pims_ipc_call(calendar_ipc_thread, CAL_IPC_MODULE, CAL_IPC_SERVER_DISCONNECT, indata, &outdata) != 0)
+    {
+        ERR("pims_ipc_call failed");
+        ret = CALENDAR_ERROR_NOT_PERMITTED;
+        goto ERROR_RETURN;
+    }
+
+    if (outdata)
+    {
+        // check outdata
+        unsigned int size = 0;
+        ret = *(int*) pims_ipc_data_get(outdata,&size);
+
+        pims_ipc_data_destroy(outdata);
+
+    }
+    else
+    {
+        ERR("ipc outdata is NULL");
+        ret = CALENDAR_ERROR_IPC;
+        goto ERROR_RETURN;
+    }
+
+    if (calendar_ipc_thread && ret == CALENDAR_ERROR_NONE)
+    {
+        pims_ipc_destroy(calendar_ipc_thread);
+        calendar_ipc_thread = NULL;
+
+        _cal_inotify_finalize();
+        _cal_view_finalize();
+    }
+
+    return ret;
+ERROR_RETURN:
+
+    return ret;
+}
+
+API int calendar_connect_with_flags(unsigned int flags)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    ret = calendar_connect();
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (flags & CALENDAR_CONNECT_FLAG_RETRY)
+        {
+            int retry_time = 500;
+            int i = 0;
+            for(i=0;i<6;i++)
+            {
+                usleep(retry_time*1000);
+                ret = calendar_connect();
+                DBG("retry cnt=%d, ret=%x",(i+1), ret);
+                if (ret == CALENDAR_ERROR_NONE)
+                    break;
+                retry_time *= 2;
+            }
+
+        }
+    }
+
+    return ret;
+}
+
+bool _cal_client_ipc_is_call_inprogress(void)
+{
+       return pims_ipc_is_call_in_progress(calendar_ipc);
+}
+
+pims_ipc_h __cal_client_ipc_get_handle(void)
+{
+    if (calendar_ipc_thread == NULL)
+    {
+        return calendar_ipc;
+    }
+    return calendar_ipc_thread;
+}
+
+void __cal_client_ipc_lock(void)
+{
+    if (calendar_ipc_thread == NULL)
+    {
+        _cal_mutex_lock(CAL_MUTEX_PIMS_IPC_CALL);
+    }
+}
+
+void __cal_client_ipc_unlock(void)
+{
+    if (calendar_ipc_thread == NULL)
+    {
+        _cal_mutex_unlock(CAL_MUTEX_PIMS_IPC_CALL);
+    }
+}
+
+int _cal_client_ipc_call(char *module, char *function, pims_ipc_h data_in,
+        pims_ipc_data_h *data_out)
+{
+    int ret = 0;
+    pims_ipc_h ipc_handle = __cal_client_ipc_get_handle();
+
+    __cal_client_ipc_lock();
+
+    ret = pims_ipc_call(ipc_handle, module, function, data_in, data_out);
+
+    __cal_client_ipc_unlock();
+
+    return ret;
+}
+
+int _cal_client_ipc_call_async(char *module, char *function, pims_ipc_h data_in,
+        pims_ipc_call_async_cb callback, void *userdata)
+{
+    int ret = 0;
+    pims_ipc_h ipc_handle = __cal_client_ipc_get_handle();
+
+    __cal_client_ipc_lock();
+
+    ret = pims_ipc_call_async(ipc_handle, module, function, data_in, callback, userdata);
+
+    __cal_client_ipc_unlock();
+
+    return ret;
+}
+
+void _cal_client_ipc_set_change_version(int version)
+{
+    if (calendar_ipc_thread == NULL)
+    {
+        calendar_change_version = version;
+        CAL_DBG("change_version=%d",version);
+        return ;
+    }
+    calendar_change_version_thread = version;
+    CAL_DBG("change_version=%d",version);
+}
+
+int _cal_client_ipc_get_change_version(void)
+{
+    if (calendar_ipc_thread == NULL)
+    {
+        return calendar_change_version;
+    }
+    return calendar_change_version_thread;
+
+}
diff --git a/client/cal_client_ipc.h b/client/cal_client_ipc.h
new file mode 100644 (file)
index 0000000..e40ae16
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CAL_CLIENT_IPC_H__
+#define __CAL_CLIENT_IPC_H__
+
+#include <pims-ipc.h>
+
+bool _cal_client_ipc_is_call_inprogress(void);
+
+int _cal_client_ipc_call(char *module, char *function, pims_ipc_h data_in,
+        pims_ipc_data_h *data_out);
+int _cal_client_ipc_call_async(char *module, char *function, pims_ipc_h data_in,
+        pims_ipc_call_async_cb callback, void *userdata);
+
+void _cal_client_ipc_set_change_version(int version);
+int _cal_client_ipc_get_change_version(void);
+
+#endif // __CAL_CLIENT_IPC_H__
diff --git a/client/calendar-service2.pc b/client/calendar-service2.pc
new file mode 100755 (executable)
index 0000000..579da21
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/calendar-service2
+
+Name: calendar-service2
+Description: calendar-service2 library
+Version: 0.1.13
+Requires: glib-2.0 alarm-service
+Libs: -L${libdir} -lcalendar-service2
+Cflags: -I${includedir}
diff --git a/common/cal_filter.c b/common/cal_filter.c
new file mode 100644 (file)
index 0000000..550cc7e
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_filter.h"
+
+static int __cal_filter_create_attribute(cal_composite_filter_s *com_filter, unsigned int property_id,
+        int match, int filter_type, cal_attribute_filter_s **out_filter);
+
+static int __cal_filter_destroy_composite(cal_composite_filter_s* filter);
+static int __cal_filter_destroy_attribute(cal_attribute_filter_s* filter);
+
+static int __cal_filter_clone_composite(cal_composite_filter_s* filter,
+        cal_composite_filter_s **out_filter);
+static int __cal_filter_clone_attribute(cal_attribute_filter_s* filter,
+        cal_attribute_filter_s **out_filter);
+
+API int calendar_filter_create( const char* view_uri, calendar_filter_h* out_filter )
+{
+    cal_composite_filter_s *com_filter;
+
+    retv_if(NULL == view_uri || NULL == out_filter, CALENDAR_ERROR_INVALID_PARAMETER);
+    com_filter = (cal_composite_filter_s *)calloc(1, sizeof(cal_composite_filter_s));
+
+    com_filter->filter_type = CAL_FILTER_COMPOSITE;
+    com_filter->view_uri = strdup(view_uri);
+    com_filter->properties = (cal_property_info_s *)_cal_view_get_property_info(view_uri, &com_filter->property_count);
+    *out_filter = (calendar_filter_h)com_filter;
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_add_operator( calendar_filter_h filter, calendar_filter_operator_e op )
+{
+    cal_composite_filter_s *com_filter;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    com_filter = (cal_composite_filter_s*)filter;
+
+    retvm_if(g_slist_length(com_filter->filter_ops) != (g_slist_length(com_filter->filters)-1),
+            CALENDAR_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 CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_add_filter( calendar_filter_h filter, calendar_filter_h add_filter)
+{
+    cal_composite_filter_s *com_filter;
+    cal_composite_filter_s *com_filter2;
+    calendar_filter_h f = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(NULL == filter || NULL == add_filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    com_filter = (cal_composite_filter_s*)filter;
+    com_filter2 = (cal_composite_filter_s*)add_filter;
+
+    retvm_if(g_slist_length(com_filter->filter_ops) != g_slist_length(com_filter->filters),
+            CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter :Please check the operator of filter");
+    retvm_if (0 != strcmp(com_filter->view_uri, com_filter2->view_uri), CALENDAR_ERROR_INVALID_PARAMETER,
+                "The filter view_uri is different (filter1:%s, filter2:%s)", com_filter->view_uri, com_filter2->view_uri);
+
+    ret = _cal_filter_clone(add_filter, &f);
+    retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+    com_filter->filters = g_slist_append(com_filter->filters, f);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_filter_create_attribute(cal_composite_filter_s *com_filter, unsigned int property_id,
+        int match, int filter_type, cal_attribute_filter_s **out_filter)
+{
+    cal_attribute_filter_s *filter;
+    //int type;
+    //bool find = false;
+
+    retvm_if(g_slist_length(com_filter->filter_ops) != g_slist_length(com_filter->filters),
+            CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter :Please check the operator of filter");
+
+    filter = (cal_attribute_filter_s *)calloc(1, sizeof(cal_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 CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_add_str( calendar_filter_h filter, unsigned int property_id, calendar_match_str_flag_e match, const char* match_value )
+{
+    cal_composite_filter_s *com_filter;
+    cal_attribute_filter_s *str_filter;
+    int ret;
+    bool bcheck;
+
+    retv_if(NULL == filter || NULL == match_value, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    bcheck = CAL_PROPERTY_CHECK_DATA_TYPE(property_id,CAL_PROPERTY_DATA_TYPE_STR);
+    retvm_if(false == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    bcheck = CAL_PROPERTY_CHECK_FLAGS(property_id,CAL_PROPERTY_FLAGS_PROJECTION);
+    retvm_if(true == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    com_filter = (cal_composite_filter_s*)filter;
+    ret = __cal_filter_create_attribute(com_filter, property_id, match, CAL_FILTER_STR, &str_filter);
+    retvm_if(CALENDAR_ERROR_NONE !=ret, ret,
+        "Invalid parameter : The paramter is not proper (view_uri:, property_id:%d, match:%d, match_value :%s",
+        property_id, match, match_value);
+
+    str_filter->value.s = SAFE_STRDUP(match_value);
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_add_int( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, int match_value )
+{
+    cal_composite_filter_s *com_filter;
+    cal_attribute_filter_s *int_filter;
+    int ret;
+    bool bcheck;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    bcheck = CAL_PROPERTY_CHECK_DATA_TYPE(property_id,CAL_PROPERTY_DATA_TYPE_INT);
+    retvm_if(false == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    bcheck = CAL_PROPERTY_CHECK_FLAGS(property_id,CAL_PROPERTY_FLAGS_PROJECTION);
+    retvm_if(true == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    com_filter = (cal_composite_filter_s*)filter;
+    ret = __cal_filter_create_attribute(com_filter, property_id, match, CAL_FILTER_INT, &int_filter);
+    retvm_if(CALENDAR_ERROR_NONE !=ret, ret,
+        "Invalid parameter : The paramter is not proper (view_uri:, property_id:%d, match:%d, match_value :%d",
+        property_id, match, match_value);
+
+    int_filter->value.i = match_value;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_add_double( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, double match_value )
+{
+    cal_composite_filter_s *com_filter;
+    cal_attribute_filter_s *int_filter;
+    int ret;
+    bool bcheck;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    bcheck = CAL_PROPERTY_CHECK_DATA_TYPE(property_id,CAL_PROPERTY_DATA_TYPE_DOUBLE);
+    retvm_if(false == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    bcheck = CAL_PROPERTY_CHECK_FLAGS(property_id,CAL_PROPERTY_FLAGS_PROJECTION);
+    retvm_if(true == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    com_filter = (cal_composite_filter_s*)filter;
+    ret = __cal_filter_create_attribute(com_filter, property_id, match, CAL_FILTER_DOUBLE, &int_filter);
+    retvm_if(CALENDAR_ERROR_NONE !=ret, ret,
+        "Invalid parameter : The paramter is not proper (view_uri:, property_id:%d, match:%d, match_value :%d",
+        property_id, match, match_value);
+
+    int_filter->value.d = match_value;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_add_lli( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, long long int match_value )
+{
+    cal_composite_filter_s *com_filter;
+    cal_attribute_filter_s *int_filter;
+    int ret;
+    bool bcheck;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    bcheck = CAL_PROPERTY_CHECK_DATA_TYPE(property_id,CAL_PROPERTY_DATA_TYPE_LLI);
+    retvm_if(false == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    bcheck = CAL_PROPERTY_CHECK_FLAGS(property_id,CAL_PROPERTY_FLAGS_PROJECTION);
+    retvm_if(true == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    com_filter = (cal_composite_filter_s*)filter;
+    ret = __cal_filter_create_attribute(com_filter, property_id, match, CAL_FILTER_LLI, &int_filter);
+    retvm_if(CALENDAR_ERROR_NONE !=ret, ret,
+        "Invalid parameter : The paramter is not proper (view_uri:, property_id:%d, match:%d, match_value :%d",
+        property_id, match, match_value);
+
+    int_filter->value.lli = match_value;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_add_caltime( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, calendar_time_s match_value )
+{
+    cal_composite_filter_s *com_filter;
+    cal_attribute_filter_s *int_filter;
+    int ret;
+    bool bcheck;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    bcheck = CAL_PROPERTY_CHECK_DATA_TYPE(property_id,CAL_PROPERTY_DATA_TYPE_CALTIME);
+    retvm_if(false == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    bcheck = CAL_PROPERTY_CHECK_FLAGS(property_id,CAL_PROPERTY_FLAGS_PROJECTION);
+    retvm_if(true == bcheck, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property_id(%d) is not supported)", property_id);
+
+    com_filter = (cal_composite_filter_s*)filter;
+    ret = __cal_filter_create_attribute(com_filter, property_id, match, CAL_FILTER_CALTIME, &int_filter);
+    retvm_if(CALENDAR_ERROR_NONE !=ret, ret,
+        "Invalid parameter : The paramter is not proper (view_uri:, property_id:%d, match:%d, match_value :%d",
+        property_id, match, match_value);
+
+    int_filter->value.caltime = match_value;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_filter_destroy( calendar_filter_h filter )
+{
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    return __cal_filter_destroy_composite((cal_composite_filter_s*)filter);
+}
+
+int _cal_filter_clone(calendar_filter_h filter, calendar_filter_h* out_filter)
+{
+    retv_if(NULL == filter || NULL == out_filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    return __cal_filter_clone_composite((cal_composite_filter_s*)filter, (cal_composite_filter_s**)out_filter);
+}
+
+static int __cal_filter_destroy_composite(cal_composite_filter_s* filter)
+{
+    GSList *cursor = NULL;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+    for(cursor=filter->filters;cursor;cursor=cursor->next)
+    {
+        cal_filter_s *src = (cal_filter_s *)cursor->data;
+        if (src == NULL)
+            continue;
+        if (src->filter_type == CAL_FILTER_COMPOSITE)
+        {
+            __cal_filter_destroy_composite((cal_composite_filter_s*)src);
+        }
+        else
+        {
+            __cal_filter_destroy_attribute((cal_attribute_filter_s*)src);
+        }
+
+    }
+    CAL_FREE(filter->view_uri);
+    g_slist_free(filter->filters);
+    g_slist_free(filter->filter_ops);
+    CAL_FREE(filter);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_filter_destroy_attribute(cal_attribute_filter_s* filter)
+{
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (filter->filter_type == CAL_FILTER_STR)
+    {
+        CAL_FREE(filter->value.s);
+    }
+    CAL_FREE(filter);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_filter_clone_composite(cal_composite_filter_s* filter,
+        cal_composite_filter_s **out_filter)
+{
+    GSList *cursor;
+    cal_composite_filter_s *out;
+    int ret = CALENDAR_ERROR_NONE;
+
+    ret = calendar_filter_create(filter->view_uri, (calendar_filter_h *)&out);
+    retv_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    for(cursor=filter->filters; cursor ; cursor=cursor->next)
+    {
+        cal_filter_s *src = (cal_filter_s *)cursor->data;
+        cal_filter_s *dest = NULL;
+
+        if (src == NULL)
+            continue;
+
+        if (src->filter_type == CAL_FILTER_COMPOSITE)
+        {
+            ret = __cal_filter_clone_composite((cal_composite_filter_s *)src,
+                    (cal_composite_filter_s **)&dest);
+        }
+        else
+        {
+            ret = __cal_filter_clone_attribute((cal_attribute_filter_s *)src,
+                    (cal_attribute_filter_s **)&dest);
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            out->filters = g_slist_append(out->filters, dest);
+        }
+        else
+        {
+            calendar_filter_destroy((calendar_filter_h)out);
+            return ret;
+        }
+    }
+
+    out->filter_ops = g_slist_copy(filter->filter_ops);
+    *out_filter = out;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_filter_clone_attribute(cal_attribute_filter_s* filter,
+        cal_attribute_filter_s **out_filter)
+{
+    cal_attribute_filter_s *out;
+    out = (cal_attribute_filter_s *)calloc(1, sizeof(cal_attribute_filter_s));
+    retv_if(NULL == out, CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    out->filter_type = filter->filter_type;
+    out->match = filter->match;
+    out->property_id = filter->property_id;
+    switch(filter->filter_type)
+    {
+    case CAL_FILTER_STR:
+        out->value.s = SAFE_STRDUP(filter->value.s);
+        break;
+    case CAL_FILTER_INT:
+        out->value.i = filter->value.i;
+        break;
+    case CAL_FILTER_DOUBLE:
+        out->value.d = filter->value.d;
+        break;
+    case CAL_FILTER_LLI:
+        out->value.lli = filter->value.lli;
+        break;
+    case CAL_FILTER_CALTIME:
+        out->value.caltime = filter->value.caltime;
+        break;
+    default:
+        break;
+    }
+
+    *out_filter = out;
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_filter.h b/common/cal_filter.h
new file mode 100644 (file)
index 0000000..8bc1b63
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_FILTER_H__
+#define __CALENDAR_SVC_FILTER_H__
+
+#include "calendar_filter.h"
+
+int _cal_filter_clone(calendar_filter_h filter, calendar_filter_h* out_filter);
+
+#endif //__CALENDAR_SVC_FILTER_H__
diff --git a/common/cal_inotify.c b/common/cal_inotify.c
new file mode 100644 (file)
index 0000000..dc62563
--- /dev/null
@@ -0,0 +1,530 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/inotify.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_inotify.h"
+
+#ifdef CAL_IPC_CLIENT
+#include "cal_client_ipc.h"
+#include "cal_mutex.h"
+#endif
+
+typedef struct
+{
+       int wd;
+       calendar_db_changed_cb callback;
+       void *cb_data;
+       cal_noti_type_e noti_type;
+       bool blocked;
+}noti_info;
+
+static int inoti_fd = -1;
+static guint inoti_handler;
+static GSList *noti_list;
+
+#ifdef CAL_IPC_CLIENT
+
+static int calendar_inoti_count = 0;
+
+void _cal_inotify_call_pending_callback(void)
+{
+    noti_info *noti;
+    GSList *cursor = NULL;
+
+    cursor = noti_list;
+    while (cursor)
+    {
+               noti = (noti_info *)cursor->data;
+               if (noti->callback && noti->blocked)
+               {
+                       noti->blocked = false;
+                       switch (noti->noti_type)
+                       {
+                       case CAL_NOTI_TYPE_CALENDAR:
+                               noti->callback(CALENDAR_VIEW_CALENDAR, noti->cb_data);
+                               break;
+                       case CAL_NOTI_TYPE_EVENT:
+                               noti->callback(CALENDAR_VIEW_EVENT, noti->cb_data);
+                               break;
+                       case CAL_NOTI_TYPE_TODO:
+                               noti->callback(CALENDAR_VIEW_TODO, noti->cb_data);
+                               break;
+                       default:
+                               break;
+                       }
+               }
+               cursor = cursor->next;
+       }
+}
+#endif
+
+static inline void _handle_callback(GSList *noti_list, int wd, uint32_t mask)
+{
+    noti_info *noti;
+    GSList *cursor;
+
+    cursor = noti_list;
+    while (cursor)
+    {
+        noti = (noti_info *)cursor->data;
+        if (noti->wd == wd)
+               {
+#ifdef CAL_IPC_CLIENT
+                       if (_cal_client_ipc_is_call_inprogress())
+                       {
+                               noti->blocked = true;
+                               continue;
+                       }
+#endif
+
+            if ((mask & IN_CLOSE_WRITE) && noti->callback)
+            {
+                switch(noti->noti_type)
+                {
+                case CAL_NOTI_TYPE_CALENDAR:
+                    noti->callback(CALENDAR_VIEW_CALENDAR, noti->cb_data);
+                    break;
+                case CAL_NOTI_TYPE_EVENT:
+                    noti->callback(CALENDAR_VIEW_EVENT, noti->cb_data);
+                    break;
+                case CAL_NOTI_TYPE_TODO:
+                    noti->callback(CALENDAR_VIEW_TODO, noti->cb_data);
+                    break;
+                default:
+                    break;
+                }
+            }
+        }
+        cursor = cursor->next;
+    }
+}
+
+static gboolean _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)
+                _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
+                        return TRUE;
+                }
+                if (ret > ie.len)
+                {
+                    ie.len = 0;
+                }
+                else
+                {
+                    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
+                        return TRUE;
+                }
+                ret += read_size;
+            }
+        }
+    }
+
+    return TRUE;
+}
+
+static inline int _inotify_attach_handler(int fd)
+{
+    guint ret;
+    GIOChannel *channel;
+
+    if (fd < 0)
+    {
+        ERR("Invalid argument: fd is NULL");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    channel = g_io_channel_unix_new(fd);
+    if (channel == NULL)
+    {
+        ERR("Failed to new channel");
+        return -1; // CALENDAR_ERROR_FAILED_INOTIFY
+    }
+
+    g_io_channel_set_flags(channel, G_IO_FLAG_NONBLOCK, NULL);
+
+    ret = g_io_add_watch(channel, G_IO_IN, _inotify_gio_cb, NULL);
+    g_io_channel_unref(channel);
+
+    return ret;
+}
+
+int _cal_inotify_initialize(void)
+{
+    int ret;
+
+#ifdef CAL_IPC_CLIENT
+    _cal_mutex_lock(CAL_MUTEX_INOTIFY);
+    calendar_inoti_count++;
+
+    if (calendar_inoti_count > 1)
+    {
+        CAL_DBG("inotify count =%d",calendar_inoti_count);
+        _cal_mutex_unlock(CAL_MUTEX_INOTIFY);
+        return CALENDAR_ERROR_NONE;
+    }
+    CAL_DBG("inotify count =%d",calendar_inoti_count);
+    _cal_mutex_unlock(CAL_MUTEX_INOTIFY);
+#endif
+    inoti_fd = inotify_init();
+    if (inoti_fd == -1)
+    {
+        ERR("Failed to init inotify(err:%d)", errno);
+#ifdef CAL_IPC_CLIENT
+        _cal_mutex_lock(CAL_MUTEX_INOTIFY);
+        calendar_inoti_count = 0;
+        _cal_mutex_unlock(CAL_MUTEX_INOTIFY);
+#endif
+        return -1; // CALENDAR_ERROR_FAILED_INOTIFY;
+    }
+
+    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 = _inotify_attach_handler(inoti_fd);
+    if (inoti_handler <= 0)
+    {
+        ERR("_inotify_attach_handler() Failed");
+        close(inoti_fd);
+        inoti_fd = -1;
+        inoti_handler = 0;
+#ifdef CAL_IPC_CLIENT
+        _cal_mutex_lock(CAL_MUTEX_INOTIFY);
+        calendar_inoti_count = 0;
+        _cal_mutex_unlock(CAL_MUTEX_INOTIFY);
+#endif
+        return -1; // CALENDAR_ERROR_FAILED_INOTIFY
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_inotify_get_wd(int fd, const char *notipath)
+{
+    return inotify_add_watch(fd, notipath, IN_ACCESS);
+}
+
+static inline int __cal_inotify_add_watch(int fd, const char *notipath)
+{
+    int ret;
+
+    ret = inotify_add_watch(fd, notipath, IN_CLOSE_WRITE);
+    if (ret < 0)
+    {
+        ERR("Failed to add watch(ret:%d)", ret);
+        return -1; // CALENDAR_ERROR_FAILED_INOTIFY
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_inotify_subscribe(cal_noti_type_e type, const char *path, calendar_db_changed_cb callback, void *data)
+{
+    int ret, wd;
+    noti_info *noti, *same_noti = NULL;
+    GSList *cursor;
+
+    if (path == NULL)
+    {
+        ERR("Invalid argument: path is NULL");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (callback == NULL)
+    {
+        ERR("Invalid argument: callback is NULL");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (inoti_fd < 0)
+    {
+        ERR("Invalid argument: iinoti_fd(%d) is invalid", inoti_fd);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    wd = __cal_inotify_get_wd(inoti_fd, path);
+    if (wd == -1)
+    {
+        ERR("Failed to get wd(err:%d)", errno);
+        return -1; // CALENDAR_ERROR_FAILED_INOTIFY
+    }
+
+    cursor = noti_list;
+    while (cursor)
+    {
+        if (cursor->data == NULL)
+        {
+            DBG("No data exist");
+            cursor = cursor->next;
+            continue;
+        }
+
+        same_noti = cursor->data;
+        if (same_noti->wd == wd && same_noti->callback == callback && same_noti->cb_data == data) {
+            break;
+
+        }
+        else
+        {
+            same_noti = NULL;
+        }
+
+        cursor = cursor->next;
+    }
+
+    if (same_noti)
+    {
+        __cal_inotify_add_watch(inoti_fd, path);
+        ERR("The same callback(%s) is already exist", path);
+        return -1; //CAL_ERR_ALREADY_EXIST;
+    }
+
+    ret = __cal_inotify_add_watch(inoti_fd, path);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("Failed to add watch");
+        return -1; // CALENDAR_ERROR_FAILED_INOTIFY
+    }
+
+    noti = calloc(1, sizeof(noti_info));
+    if (noti == NULL)
+    {
+        ERR("Failed to alloc");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+
+    noti->wd = wd;
+    noti->cb_data = data;
+    noti->callback = callback;
+    noti->noti_type = type;
+       noti->blocked = false;
+    noti_list = g_slist_append(noti_list, noti);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_inotify_delete_noti_with_data(GSList **noti_list, int wd,
+        calendar_db_changed_cb callback, void *user_data)
+{
+    int del_cnt, remain_cnt;
+    GSList *cursor, *result;
+
+    del_cnt = 0;
+    remain_cnt = 0;
+
+    cursor = result = *noti_list;
+    while (cursor)
+    {
+        noti_info *noti = cursor->data;
+        if (noti && wd == noti->wd)
+        {
+            if (callback == noti->callback && user_data == noti->cb_data) {
+                cursor = cursor->next;
+                result = g_slist_remove(result , noti);
+                free(noti);
+                del_cnt++;
+                continue;
+            }
+            else
+            {
+                remain_cnt++;
+            }
+        }
+        cursor = cursor->next;
+    }
+
+    if (del_cnt == 0)
+    {
+        ERR("Nothing to delete");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+
+    *noti_list = result;
+
+    return remain_cnt;
+}
+
+static inline int __cal_notify_delete_noti(GSList **noti_list, int wd, calendar_db_changed_cb callback)
+{
+    int del_cnt, remain_cnt;
+    GSList *cursor, *result;
+
+    del_cnt = 0;
+    remain_cnt = 0;
+
+    cursor = result = *noti_list;
+    while (cursor)
+    {
+        noti_info *noti = cursor->data;
+        if (noti && wd == noti->wd)
+        {
+            if (NULL == callback || noti->callback == callback)
+            {
+                cursor = cursor->next;
+                result = g_slist_remove(result, noti);
+                free(noti);
+                del_cnt++;
+                continue;
+            }
+            else
+            {
+                remain_cnt++;
+            }
+        }
+        cursor = cursor->next;
+    }
+
+    if (del_cnt == 0)
+    {
+        ERR("Nothing to delete");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+
+    *noti_list = result;
+
+    return remain_cnt;
+}
+
+int _cal_inotify_unsubscribe_with_data(const char *path, calendar_db_changed_cb callback, void *user_data)
+{
+    int wd;
+    int ret;
+
+    if (path == NULL)
+    {
+        ERR("Invalid argument: path is NULL");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (callback == NULL)
+    {
+        ERR("Invalid argument: callback is NULL");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (inoti_fd < 0)
+    {
+        ERR("Invalid argument: iinoti_fd(%d) is invalid", inoti_fd);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    wd = __cal_inotify_get_wd(inoti_fd, path);
+    if (wd == -1)
+    {
+        ERR("Failed to get wd(err:%d)", errno);
+        return -1; // CALENDAR_ERROR_FAILED_INOTIFY
+    }
+
+    ret = __cal_inotify_delete_noti_with_data(&noti_list, wd, callback, user_data);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        WARN("Failed to delete noti(err:%d)", ret);
+        return __cal_inotify_add_watch(inoti_fd, path);
+    }
+
+    return inotify_rm_watch(inoti_fd, wd);
+}
+
+static inline gboolean __cal_inotify_detach_handler(guint id)
+{
+    return g_source_remove(id);
+}
+
+static void __clear_nslot_list(gpointer data, gpointer user_data)
+{
+    free(data);
+}
+
+void _cal_inotify_finalize(void)
+{
+#ifdef CAL_IPC_CLIENT
+    _cal_mutex_lock(CAL_MUTEX_INOTIFY);
+    calendar_inoti_count--;
+
+    if (calendar_inoti_count > 0)
+    {
+        CAL_DBG("inotify count =%d",calendar_inoti_count);
+        _cal_mutex_unlock(CAL_MUTEX_INOTIFY);
+        return ;
+    }
+    CAL_DBG("inotify count =%d",calendar_inoti_count);
+    _cal_mutex_unlock(CAL_MUTEX_INOTIFY);
+#endif
+    if (inoti_handler)
+    {
+        __cal_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 (inoti_fd >= 0)
+    {
+        close(inoti_fd);
+        inoti_fd = -1;
+    }
+}
+
diff --git a/common/cal_inotify.h b/common/cal_inotify.h
new file mode 100644 (file)
index 0000000..f4cafe3
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_INOTIFY_H__
+#define __CALENDAR_SVC_INOTIFY_H__
+
+#include "calendar_types2.h"
+
+#ifdef CAL_IPC_CLIENT
+void _cal_inotify_call_pending_callback(void);
+#endif
+
+int _cal_inotify_initialize(void);
+int _cal_inotify_subscribe(cal_noti_type_e type, const char *path, calendar_db_changed_cb callback, void *data);
+int _cal_inotify_unsubscribe_with_data(const char *path, calendar_db_changed_cb callback, void *user_data);
+void _cal_inotify_finalize(void);
+
+#endif // __CALENDAR_SVC_INOTIFY_H__
diff --git a/common/cal_internal.h b/common/cal_internal.h
new file mode 100644 (file)
index 0000000..36b9032
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_INTERNAL_H__
+#define __CALENDAR_SVC_INTERNAL_H__
+
+#include <stdio.h>
+#include <string.h>
+
+#define EVENT_UPDATE "calendar_event_update"
+#define CALENDARBOOK_UPDATE "calendar_book_update"
+#define TASK_UPDATE "task_update"
+
+#define PKG_CALENDAR_APP "org.tizen.calendar"
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#define SAFE_STRDUP(src) (src)?strdup((char *)src):NULL
+
+#define CAL_DEBUGGING
+
+#define LOG_TAG "CALENDAR_SVC"
+#include <dlog.h>
+#define DLOG(prio, fmt, arg...) \
+  do { SLOG(prio, LOG_TAG, fmt, ##arg); } while(0);
+#define INFO(fmt, arg...) SLOGI(fmt, ##arg)
+#define WARN(fmt, arg...) SLOGW("%s:%d " fmt, __FUNCTION__, __LINE__, ##arg)
+#define ERR(fmt, arg...) SLOGE("%s:%d " fmt, __FUNCTION__, __LINE__, ##arg)
+#define DBG(fmt, arg...) SLOGD("%s:" fmt, __FUNCTION__, ##arg)
+
+//#define CAL_DEBUGGING
+#ifdef CAL_DEBUGGING
+    #if defined(CAL_IPC_SERVER)
+    #define CAL_FN_CALL DBG("SERVER:>>>>>>>>%s called", __FUNCTION__)
+    #define CAL_FN_END DBG("SERVER:<<<<<<<<%s ended", __FUNCTION__)
+    #elif defined(CAL_IPC_CLIENT)
+    #define CAL_FN_CALL DBG("CLIENT:>>>>>>>>%s called", __FUNCTION__)
+    #define CAL_FN_END DBG("CLIENT:<<<<<<<<%s ended", __FUNCTION__)
+    #else
+    #define CAL_FN_CALL DBG(">>>>>>>>%s called", __FUNCTION__)
+    #define CAL_FN_END DBG("<<<<<<<<%s ended", __FUNCTION__)
+    #endif
+
+    #if defined(CAL_IPC_SERVER)
+    #define CAL_DBG(fmt, arg...) DBG("SERVER:%d " fmt, __LINE__, ##arg)
+    #elif defined(CAL_IPC_CLIENT)
+    #define CAL_DBG(fmt, arg...) DBG("CLIENT:%d " fmt, __LINE__, ##arg)
+    #else
+    #define CAL_DBG(fmt, arg...) DBG("%d " fmt, __LINE__, ##arg)
+    #endif
+#else /* CAL_DEBUGGING */
+#define CAL_FN_CALL
+#define CAL_FN_END
+#define CAL_DBG(fmt, arg...)
+#endif /* CAL_DEBUGGING */
+
+
+#define TMDUMP(_X_)\
+{\
+       ERR("tm(%d/%d/%d %d:%d)",(_X_).tm_year+1900,(_X_).tm_mon+1,(_X_).tm_mday,(_X_).tm_hour,(_X_).tm_min);\
+}
+
+#define warn_if(expr, fmt, arg...) do { \
+       if (expr) { \
+               WARN(fmt, ##arg); \
+       } \
+} while (0)
+#define ret_if(expr) do { \
+       if (expr) { \
+               ERR("(%s)", #expr); \
+               return; \
+       } \
+} while (0)
+#define retv_if(expr, val) do { \
+       if (expr) { \
+               ERR("(%s)", #expr); \
+               return (val); \
+       } \
+} while (0)
+#define retm_if(expr, fmt, arg...) do { \
+       if (expr) { \
+               ERR(fmt, ##arg); \
+               return; \
+       } \
+} while (0)
+#define retvm_if(expr, val, fmt, arg...) do { \
+       if (expr) { \
+               ERR(fmt, ##arg); \
+               return (val); \
+       } \
+} while (0)
+
+#define retex_if(expr, val, fmt, arg...) do { \
+         if(expr) { \
+                ERR(fmt, ##arg); \
+                val; \
+                goto CATCH; \
+         } \
+       } while (0);
+
+#define CAL_PROFILE
+#ifdef CAL_PROFILE
+#define CAL_PROFILE_GET_TIME() (clock() / (CLOCKS_PER_SEC / 1000));
+#define CAL_PROFILE_PRINT(starttime,endtime) ERR("%ld ~ %ld : %ld(%d sec) msec",starttime,endtime,endtime-starttime,(endtime-starttime)/1000);
+#else
+#define CAL_PROFILE_GET_TIME(input_time) 0
+#define CAL_PROFILE_PRINT(starttime,endtime)
+#endif
+
+#define CAL_FREE(ptr) \
+ do { \
+  if (ptr) \
+    free(ptr); \
+  ptr = NULL; \
+ } while(0)
+
+#define ASSERT_NOT_REACHED(fmt, arg...) do { \
+       ERR(fmt, ##arg); \
+       g_assert_not_reached(); \
+} while(0)
+
+// Thread-local storage
+#if defined(CAL_IPC_SERVER)
+#define TLS __thread
+#elif defined(CAL_IPC_CLIENT)
+#define TLS __thread
+#else   //CAL_NATIVE
+#define TLS
+#endif
+
+#endif /* __CALENDAR_SVC_INTERNAL_H__ */
+
diff --git a/common/cal_list.c b/common/cal_list.c
new file mode 100644 (file)
index 0000000..ec179d5
--- /dev/null
@@ -0,0 +1,303 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_list.h"
+
+API int calendar_list_create( calendar_list_h* out_list )
+{
+       cal_list_s *l;
+
+       l = (cal_list_s *)calloc(1, sizeof(cal_list_s));
+       if (l == NULL) {
+               ERR("Failed to calloc");
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       l->count = 0;
+       l->record = NULL;
+       l->cursor = NULL;
+
+       *out_list = (calendar_list_h)l;
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_get_count( calendar_list_h list, int *count )
+{
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (count == NULL) {
+               ERR("Invalid argument: count is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    l = (cal_list_s *)list;
+
+       *count = l->count;
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_add( calendar_list_h list, calendar_record_h record )
+{
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (record == NULL) {
+               ERR("Invalid argument: calendar_record_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+
+       l->count++;
+       l->record = g_list_append(l->record, record);
+       //l->cursor = g_list_nth(l->record, (l->count) -1);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_remove( calendar_list_h list, calendar_record_h record )
+{
+       GList *cursor;
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (record == NULL) {
+               ERR("Invalid argument: calendar_record_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+
+       cursor = l->record;
+       while (cursor) {
+               if (cursor->data == record) {
+                       DBG("Found record and remove");
+                       l->record = g_list_remove(l->record,cursor->data);
+                       //calendar_record_destroy((calendar_record_h)(cursor->data));
+                       l->count--;
+                       return CALENDAR_ERROR_NONE;
+               }
+               cursor = cursor->next;
+       }
+       return CALENDAR_ERROR_NO_DATA;
+}
+
+API int calendar_list_get_current_record_p( calendar_list_h list, calendar_record_h* record )
+{
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (record == NULL) {
+               ERR("Invalid argument: calendar_record_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+       if (l->cursor == NULL) {
+               ERR("No current data");
+               *record = NULL;
+               return CALENDAR_ERROR_NO_DATA;
+       }
+
+       *record = l->cursor->data;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_prev( calendar_list_h list )
+{
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+       l->cursor = g_list_previous(l->cursor);
+       if (l->cursor == NULL) {
+               DBG("No prev list");
+               return CALENDAR_ERROR_NO_DATA;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_next( calendar_list_h list )
+{
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+       l->cursor = g_list_next(l->cursor);
+       if (l->cursor == NULL) {
+               DBG("No next list");
+               return CALENDAR_ERROR_NO_DATA;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_first( calendar_list_h list )
+{
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+       l->cursor = g_list_first(l->record);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_last( calendar_list_h list )
+{
+       cal_list_s *l;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+       l->cursor = g_list_last(l->record);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_list_destroy( calendar_list_h list, bool delete_record )
+{
+       GList *cursor;
+       cal_list_s *l = NULL;
+
+       if (list == NULL) {
+               ERR("Invalid argument: calendar_list_h is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       l = (cal_list_s *)list;
+
+       if (delete_record == true)
+       {
+        cursor = l->record;
+
+        while (cursor)
+        {
+            if (cursor->data)
+            {
+                calendar_record_destroy((calendar_record_h)(cursor->data), true);
+            }
+            cursor = cursor->next;
+        }
+       }
+       if(l->record)
+       {
+           g_list_free(l->record);
+       }
+       CAL_FREE(l);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_list_clone(calendar_list_h list, calendar_list_h *out_list)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    int count = 0, i = 0;
+       calendar_list_h l = NULL;
+
+       if (NULL == list || NULL == out_list)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    ret = calendar_list_get_count(list, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               return ret;
+       }
+
+    ret = calendar_list_first(list);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               return ret;
+       }
+
+    ret = calendar_list_create(&l);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               return ret;
+       }
+
+    for(i = 0; i < count; i++)
+    {
+        calendar_record_h record = NULL;
+        calendar_record_h clone_record = NULL;
+        if (calendar_list_get_current_record_p(list,&record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_list_get_count fail");
+            calendar_list_destroy(l, true);
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+
+        if (calendar_record_clone(record, &clone_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_list_get_count fail");
+            calendar_list_destroy(l, true);
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+
+        if (calendar_list_add(l, clone_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_list_get_count fail");
+            calendar_list_destroy(l, true);
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+
+        calendar_list_next(list);
+    }
+
+       *out_list = l;
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_list.h b/common/cal_list.h
new file mode 100644 (file)
index 0000000..5e38d2e
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_LIST_H__
+#define __CALENDAR_SVC_LIST_H__
+
+#include "calendar_list.h"
+
+int _cal_list_clone(calendar_list_h list, calendar_list_h *out_list);
+
+#endif // __CALENDAR_SVC_LIST_H__
diff --git a/common/cal_mutex.c b/common/cal_mutex.c
new file mode 100644 (file)
index 0000000..c4a89fa
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_mutex.h"
+
+static pthread_mutex_t __cal_property_hash_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t __cal_connection_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t __cal_pims_ipc_call_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t __cal_inotify_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static inline pthread_mutex_t* cts_mutex_get_mutex(int type)
+{
+    pthread_mutex_t *ret_val;
+
+    switch (type) {
+    case CAL_MUTEX_PROPERTY_HASH:
+        ret_val = &__cal_property_hash_mutex;
+        break;
+    case CAL_MUTEX_CONNECTION:
+        ret_val = &__cal_connection_mutex;
+        break;
+    case CAL_MUTEX_PIMS_IPC_CALL:
+        ret_val = &__cal_pims_ipc_call_mutex;
+        break;
+    case CAL_MUTEX_INOTIFY:
+        ret_val = &__cal_inotify_mutex;
+        break;
+    default:
+        ERR("unknown type(%d)", type);
+        ret_val = NULL;
+        break;
+    }
+    return ret_val;
+}
+
+void _cal_mutex_lock(int type)
+{
+    int ret;
+    pthread_mutex_t *mutex;
+
+    mutex = cts_mutex_get_mutex(type);
+
+    if (mutex != NULL)
+    {
+        ret = pthread_mutex_lock(mutex);
+        retm_if(ret, "mutex_lock Failed(%d)", ret);
+    }
+}
+
+void _cal_mutex_unlock(int type)
+{
+    int ret;
+    pthread_mutex_t *mutex;
+
+    mutex = cts_mutex_get_mutex(type);
+
+    if (mutex != NULL)
+    {
+        ret = pthread_mutex_unlock(mutex);
+        retm_if(ret, "mutex_unlock Failed(%d)", ret);
+    }
+}
diff --git a/common/cal_mutex.h b/common/cal_mutex.h
new file mode 100644 (file)
index 0000000..10866d3
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_MUTEX_H__
+#define __CALENDAR_SVC_MUTEX_H__
+
+enum {
+    CAL_MUTEX_CONNECTION,
+    CAL_MUTEX_PIMS_IPC_CALL,
+    CAL_MUTEX_INOTIFY,
+    CAL_MUTEX_PROPERTY_HASH,
+};
+
+void _cal_mutex_lock(int type);
+void _cal_mutex_unlock(int type);
+
+#endif  //__CALENDAR_SVC_MUTEX_H__
diff --git a/common/cal_query.c b/common/cal_query.c
new file mode 100644 (file)
index 0000000..9571c3d
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_filter.h"
+
+#include "cal_query.h"
+
+static bool __cal_query_property_check(const cal_property_info_s *properties,
+        int count, unsigned int property_id);
+
+static bool __cal_query_property_check(const cal_property_info_s *properties,
+        int count, unsigned int property_id)
+{
+    int i;
+
+    for (i=0;i<count;i++)
+    {
+        cal_property_info_s *p = (cal_property_info_s*)&(properties[i]);
+        if (property_id == p->property_id) {
+            return true;
+        }
+    }
+    return false;
+}
+
+API int calendar_query_create( const char* view_uri, calendar_query_h* out_query )
+{
+    cal_query_s *query;
+
+    retv_if(NULL == view_uri || NULL == out_query, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    query = (cal_query_s *)calloc(1, sizeof(cal_query_s));
+    query->view_uri = strdup(view_uri);
+    query->properties = (cal_property_info_s *)_cal_view_get_property_info(view_uri, &query->property_count);
+    *out_query = (calendar_query_h)query;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_query_set_projection(calendar_query_h query, unsigned int property_ids[], int count)
+{
+    cal_query_s *que = NULL;
+    int i;
+    bool find;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    que = (cal_query_s *)query;
+
+    for (i=0;i<count;i++)
+    {
+        find = __cal_query_property_check(que->properties, que->property_count, property_ids[i]);
+        retvm_if(false == find, CALENDAR_ERROR_INVALID_PARAMETER,
+                    "Invalid parameter : property_id(%d) is not supported on view_uri(%s)", property_ids[i], que->view_uri);
+
+        find = CAL_PROPERTY_CHECK_FLAGS(property_ids[i], CAL_PROPERTY_FLAGS_FILTER);
+        retvm_if(true == find, CALENDAR_ERROR_INVALID_PARAMETER,
+                    "Invalid parameter : property_id(%d) is not supported on view_uri(%s)", property_ids[i], que->view_uri);
+    }
+
+    CAL_FREE(que->projection);
+
+    que->projection = calloc(count, sizeof(unsigned int));
+    memcpy(que->projection, property_ids, sizeof(unsigned int) * count);
+    que->projection_count = count;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_query_set_distinct(calendar_query_h query, bool set)
+{
+    cal_query_s *que = NULL;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    que = (cal_query_s *)query;
+
+    que->distinct = set;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_query_set_filter(calendar_query_h query, calendar_filter_h filter)
+{
+    cal_query_s *que;
+    calendar_filter_h new_filter;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(NULL == query || NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    que = (cal_query_s *)query;
+
+       if(((cal_composite_filter_s*)filter)->filters == NULL)
+       {
+               ERR("Empty filter");
+               return CALENDAR_ERROR_NO_DATA;
+       }
+
+    ret = _cal_filter_clone(filter,&new_filter);
+    retv_if(ret!=CALENDAR_ERROR_NONE, ret);
+
+    if (que->filter)
+    {
+        calendar_filter_destroy((calendar_filter_h)que->filter);
+    }
+
+    que->filter = (cal_composite_filter_s*)new_filter;
+
+    return ret;
+}
+
+API int calendar_query_set_sort(calendar_query_h query, unsigned int property_id, bool asc)
+{
+    cal_query_s *que;
+    bool find = false;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    que = (cal_query_s *)query;
+
+
+    find = __cal_query_property_check(que->properties, que->property_count, property_id);
+    retvm_if(false == find, CALENDAR_ERROR_INVALID_PARAMETER,
+                "Invalid paramter : property_id(%d) is not supported on view_uri(%s)", property_id, que->view_uri);
+
+    que->sort_property_id = property_id;
+    que->asc = asc;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_query_destroy( calendar_query_h query )
+{
+    cal_query_s *que;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    que = (cal_query_s *)query;
+
+    if (que->filter)
+    {
+        calendar_filter_destroy((calendar_filter_h)que->filter);
+    }
+
+    CAL_FREE(que->view_uri);
+    CAL_FREE(que->projection);
+    CAL_FREE(que);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_query_clone(calendar_query_h query, calendar_query_h* out_query)
+{
+    cal_query_s *que;
+    cal_query_s *out_que;
+    cal_filter_s *out_filter = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    que = (cal_query_s *)query;
+
+    ret = calendar_query_create(que->view_uri, out_query);
+    retv_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_OUT_OF_MEMORY);
+    out_que = (cal_query_s *)*out_query;
+
+    if (que->filter)
+    {
+        _cal_filter_clone((calendar_filter_h)que->filter,(calendar_filter_h*)&out_filter);
+    }
+
+    if (que->projection_count > 0)
+    {
+        out_que->projection = calloc(que->projection_count, sizeof(unsigned int));
+        memcpy(out_que->projection, que->projection , sizeof(unsigned int) * que->projection_count);
+        out_que->projection_count = que->projection_count;
+    }
+    out_que->sort_property_id = que->sort_property_id;
+    out_que->asc = que->asc;
+
+    return CALENDAR_ERROR_NONE;
+}
+
diff --git a/common/cal_query.h b/common/cal_query.h
new file mode 100644 (file)
index 0000000..85e847a
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_QUERY_H__
+#define __CALENDAR_SVC_QUERY_H__
+
+#include "calendar_query.h"
+
+int _cal_query_clone(calendar_query_h query, calendar_query_h* out_query);
+
+#endif  //__CALENDAR_SVC_QUERY_H__
diff --git a/common/cal_record.c b/common/cal_record.c
new file mode 100644 (file)
index 0000000..666f131
--- /dev/null
@@ -0,0 +1,543 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>           //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+#define __CHECK_READ_ONLY_PROPERTY() \
+    if (CAL_PROPERTY_CHECK_FLAGS(property_id,CAL_PROPERTY_FLAGS_READ_ONLY) == true) \
+    { \
+        ERR("Invalid parameter: Don't try to change read-only property."); \
+        return CALENDAR_ERROR_NOT_PERMITTED; \
+    }
+
+extern cal_record_plugin_cb_s _cal_record_calendar_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_event_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_todo_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_alarm_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_attendee_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_timezone_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_updated_info_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_instance_normal_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_instance_allday_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_search_plugin_cb;
+extern cal_record_plugin_cb_s _cal_record_extended_plugin_cb;
+
+cal_record_plugin_cb_s* _cal_record_get_plugin_cb(cal_record_type_e type)
+{
+       switch (type)
+       {
+       case CAL_RECORD_TYPE_CALENDAR:
+               return (&_cal_record_calendar_plugin_cb);
+       case CAL_RECORD_TYPE_EVENT:
+               return (&_cal_record_event_plugin_cb);
+       case CAL_RECORD_TYPE_TODO:
+               return (&_cal_record_todo_plugin_cb);
+       case CAL_RECORD_TYPE_ALARM:
+               return (&_cal_record_alarm_plugin_cb);
+       case CAL_RECORD_TYPE_ATTENDEE:
+               return (&_cal_record_attendee_plugin_cb);
+       case CAL_RECORD_TYPE_TIMEZONE:
+               return (&_cal_record_timezone_plugin_cb);
+       case CAL_RECORD_TYPE_INSTANCE_NORMAL:
+           return (&_cal_record_instance_normal_plugin_cb);
+       case CAL_RECORD_TYPE_INSTANCE_ALLDAY:
+           return (&_cal_record_instance_allday_plugin_cb);
+       case CAL_RECORD_TYPE_UPDATED_INFO:
+           return (&_cal_record_updated_info_plugin_cb);
+    case CAL_RECORD_TYPE_SEARCH:
+        return (&_cal_record_search_plugin_cb);
+    case CAL_RECORD_TYPE_EXTENDED:
+        return (&_cal_record_extended_plugin_cb);
+       default:
+               return NULL;
+       }
+}
+
+static inline void __cal_record_set_property_flag(calendar_record_h record, unsigned int property_id, cal_properties_flag_e flag)
+{
+       int index;
+       cal_record_s *_record = NULL;
+
+       _record = (cal_record_s *)record;
+       index = property_id & 0x00000FFF;
+
+       if (_record->properties_flags == NULL)
+       {
+        int count = 0;
+        _cal_view_get_property_info(_record->view_uri,&count);
+
+        if (count > 0)
+        {
+            _record->properties_flags = calloc(count, sizeof(char));
+            _record->properties_max_count = count;
+            if (_record->properties_flags == NULL)
+            {
+                ERR("calloc fail");
+                return ;
+            }
+        }
+        else
+        {
+            ERR("get property_info_fail");
+            return ;
+        }
+       }
+
+       _record->properties_flags[index] |= flag;
+       _record->property_flag |= flag;
+}
+
+bool _cal_record_check_property_flag(calendar_record_h record, unsigned int property_id, cal_properties_flag_e flag)
+{
+       int index;
+       cal_record_s *_record = NULL;
+
+       _record = (cal_record_s *)record;
+       index = property_id & 0x00000FFF;
+
+       if (_record->properties_flags == NULL)
+       {
+           if (flag == CAL_PROPERTY_FLAG_PROJECTION)
+               return true;
+           else
+               return false;
+       }
+
+    if (flag == CAL_PROPERTY_FLAG_PROJECTION)
+    {
+        if (_record->property_flag & CAL_PROPERTY_FLAG_PROJECTION )
+        {
+            if (_record->properties_flags[index] & CAL_PROPERTY_FLAG_PROJECTION )
+                return true;
+            else
+                return false;
+        }
+
+        return true;
+    }
+
+       return (_record->properties_flags[index] & flag) ? true : false;
+
+}
+
+int _cal_record_set_projection(calendar_record_h record, const unsigned int *projection, const int projection_count, int properties_max_count)
+{
+       int i;
+
+       cal_record_s *_record = NULL;
+
+       retv_if(record == NULL, -1);
+
+       _record = (cal_record_s *)record;
+
+       CAL_FREE(_record->properties_flags);
+       _record->properties_flags  = calloc(properties_max_count, sizeof(char));
+
+    retvm_if(NULL == _record->properties_flags, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc fail");
+
+       _record->properties_max_count = properties_max_count;
+
+       for (i = 0; i < projection_count; i++)
+       {
+               __cal_record_set_property_flag(record, projection[i], CAL_PROPERTY_FLAG_PROJECTION);
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_record_create( const char* view_uri, calendar_record_h* out_record )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    retvm_if(NULL == view_uri || NULL == out_record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    type =_cal_view_get_type(view_uri);
+    retv_if(CAL_RECORD_TYPE_INVALID == type, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    cal_record_plugin_cb_s *plugin_cb = _cal_record_get_plugin_cb(type);
+    retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == plugin_cb->create, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = plugin_cb->create(out_record);
+
+    if(ret == CALENDAR_ERROR_NONE)
+    {
+        CAL_RECORD_INIT_COMMON((cal_record_s*)*out_record, type, plugin_cb, _cal_view_get_uri(view_uri));
+    }
+
+    return ret;
+}
+
+API int calendar_record_destroy( calendar_record_h record, bool delete_child )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == temp->plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->destroy, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       CAL_FREE(temp->properties_flags);
+
+       ret = temp->plugin_cb->destroy(record, delete_child);
+
+       return ret;
+}
+
+API int calendar_record_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->clone, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->clone(record, out_record);
+
+       return ret;
+}
+
+API int calendar_record_get_uri_p( calendar_record_h record, char** out_str )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == out_str, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    *out_str = (char*)(temp->view_uri);
+
+    return ret;
+}
+
+// Record get/set int,str, etc..
+API int calendar_record_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_str, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_str, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_str(record, property_id, out_str);
+
+       return ret;
+}
+
+API int calendar_record_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_str, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_str_p, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_str_p(record, property_id, out_str);
+
+       return ret;
+}
+API int calendar_record_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_value, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_int, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_int(record, property_id, out_value);
+
+       return ret;
+}
+
+API int calendar_record_get_double( calendar_record_h record, unsigned int property_id, double* out_value )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_value, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_double, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_double(record, property_id, out_value);
+
+       return ret;
+}
+API int calendar_record_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_value, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_lli, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_lli(record, property_id, out_value);
+
+       return ret;
+}
+
+API int calendar_record_get_caltime(calendar_record_h record, unsigned int property_id, calendar_time_s *out_value )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_value, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_caltime, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_caltime(record, property_id, out_value);
+
+       return ret;
+}
+
+API int calendar_record_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    __CHECK_READ_ONLY_PROPERTY();
+
+    int ret = _cal_record_set_str(record, property_id, value);
+
+       return ret;
+}
+
+API int calendar_record_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    __CHECK_READ_ONLY_PROPERTY();
+
+    int ret = _cal_record_set_int(record, property_id, value);
+
+    return ret;
+}
+
+API int calendar_record_set_double( calendar_record_h record, unsigned int property_id, double value )
+{
+    retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    __CHECK_READ_ONLY_PROPERTY();
+
+    int ret = _cal_record_set_double(record, property_id, value);
+
+    return ret;
+}
+
+API int calendar_record_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+    retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    __CHECK_READ_ONLY_PROPERTY();
+
+    int ret = _cal_record_set_lli(record, property_id, value);
+
+    return ret;
+}
+
+API int calendar_record_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value )
+{
+    retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    __CHECK_READ_ONLY_PROPERTY();
+
+    int ret = _cal_record_set_caltime(record, property_id, value);
+
+    return ret;
+}
+
+// Record get/set child records
+API int calendar_record_add_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == child_record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->add_child_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->add_child_record(record, property_id, child_record);
+
+       return ret;
+}
+API int calendar_record_remove_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == child_record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->remove_child_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->remove_child_record(record, property_id, child_record);
+
+       return ret;
+}
+
+API int calendar_record_get_child_record_count( calendar_record_h record, unsigned int property_id, unsigned int* count  )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_child_record_count, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_child_record_count(record, property_id, count);
+
+       return ret;
+}
+API int calendar_record_get_child_record_at_p( calendar_record_h record, unsigned int property_id, int index, calendar_record_h* child_record )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == child_record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->get_child_record_at_p, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->get_child_record_at_p(record, property_id, index, child_record);
+
+       return ret;
+}
+
+API int calendar_record_clone_child_record_list( calendar_record_h record, unsigned int property_id, calendar_list_h* out_list )
+{
+       int ret = CALENDAR_ERROR_NONE;
+
+       cal_record_s *temp = (cal_record_s*)(record);
+
+       retvm_if(NULL == record || NULL == temp->plugin_cb || NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == temp->plugin_cb->clone_child_record_list, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+       retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = temp->plugin_cb->clone_child_record_list(record, property_id, out_list);
+
+       return ret;
+}
+
+int _cal_record_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == temp->plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == temp->plugin_cb->set_str, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+    retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = temp->plugin_cb->set_str(record, property_id, value);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        __cal_record_set_property_flag(record,property_id,CAL_PROPERTY_FLAG_DIRTY);
+    }
+    return ret;
+}
+
+int _cal_record_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == temp->plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == temp->plugin_cb->set_int, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+    retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = temp->plugin_cb->set_int(record, property_id, value);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        __cal_record_set_property_flag(record,property_id,CAL_PROPERTY_FLAG_DIRTY);
+    }
+    return ret;
+}
+
+int _cal_record_set_double( calendar_record_h record, unsigned int property_id, double value )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == temp->plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == temp->plugin_cb->set_double, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+    retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = temp->plugin_cb->set_double(record, property_id, value);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        __cal_record_set_property_flag(record,property_id,CAL_PROPERTY_FLAG_DIRTY);
+    }
+    return ret;
+}
+
+int _cal_record_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == temp->plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == temp->plugin_cb->set_lli, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+    retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = temp->plugin_cb->set_lli(record, property_id, value);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        __cal_record_set_property_flag(record,property_id,CAL_PROPERTY_FLAG_DIRTY);
+    }
+    return ret;
+}
+
+int _cal_record_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == temp->plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == temp->plugin_cb->set_caltime, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+    retvm_if(false == _cal_record_check_property_flag(record, property_id,CAL_PROPERTY_FLAG_PROJECTION), CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = temp->plugin_cb->set_caltime(record, property_id, value);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        __cal_record_set_property_flag(record,property_id,CAL_PROPERTY_FLAG_DIRTY);
+    }
+    return ret;
+}
diff --git a/common/cal_record.h b/common/cal_record.h
new file mode 100644 (file)
index 0000000..130ebbd
--- /dev/null
@@ -0,0 +1,150 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_RECORD_H__
+#define __CALENDAR_SVC_RECORD_H__
+
+#include "calendar_record.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum
+{
+    CAL_RECORD_TYPE_INVALID = 0,
+    CAL_RECORD_TYPE_CALENDAR,
+    CAL_RECORD_TYPE_EVENT ,
+    CAL_RECORD_TYPE_TODO,
+    CAL_RECORD_TYPE_TIMEZONE,
+    CAL_RECORD_TYPE_ATTENDEE,
+    CAL_RECORD_TYPE_ALARM,
+    CAL_RECORD_TYPE_INSTANCE_NORMAL,
+    CAL_RECORD_TYPE_INSTANCE_ALLDAY,
+    CAL_RECORD_TYPE_UPDATED_INFO,
+    CAL_RECORD_TYPE_SEARCH,
+    CAL_RECORD_TYPE_EXTENDED,
+
+} cal_record_type_e;
+
+typedef int (*cal_record_create_cb)( calendar_record_h* out_record );
+typedef int (*cal_record_destroy_cb)( calendar_record_h record, bool delete_child );
+typedef int (*cal_record_clone_cb)( calendar_record_h record, calendar_record_h* out_record );
+typedef int (*cal_record_get_str_cb)( calendar_record_h record, unsigned int property_id, char** out_str );
+typedef int (*cal_record_get_str_p_cb)( calendar_record_h record, unsigned int property_id, char** out_str );
+typedef int (*cal_record_get_int_cb)( calendar_record_h record, unsigned int property_id, int* out_value );
+typedef int (*cal_record_get_double_cb)( calendar_record_h record, unsigned int property_id, double* out_value );
+typedef int (*cal_record_get_lli_cb)( calendar_record_h record, unsigned int property_id, long long int* out_value );
+typedef int (*cal_record_get_caltime_cb)( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value );
+typedef int (*cal_record_set_str_cb)( calendar_record_h record, unsigned int property_id, const char* value );
+typedef int (*cal_record_set_int_cb)( calendar_record_h record, unsigned int property_id, int value );
+typedef int (*cal_record_set_double_cb)( calendar_record_h record, unsigned int property_id, double value );
+typedef int (*cal_record_set_lli_cb)( calendar_record_h record, unsigned int property_id, long long int value );
+typedef int (*cal_record_set_caltime_cb)( calendar_record_h record, unsigned int property_id, calendar_time_s value );
+typedef int (*cal_record_add_child_record_cb)( calendar_record_h record, unsigned int property_id, calendar_record_h child_record );
+typedef int (*cal_record_remove_child_record_cb)( calendar_record_h record, unsigned int property_id, calendar_record_h child_record );
+typedef int (*cal_record_get_child_record_count_cb)( calendar_record_h record, unsigned int property_id, unsigned int* count );
+typedef int (*cal_record_get_child_record_at_p_cb)( calendar_record_h record, unsigned int property_id, int index, calendar_record_h* child_record );
+typedef int (*cal_record_clone_child_record_list_cb)( calendar_record_h record, unsigned int property_id, calendar_list_h* out_list );
+
+typedef enum {
+       CAL_PROPERTY_FLAG_PROJECTION = 0x00000001,
+       CAL_PROPERTY_FLAG_DIRTY = 0x00000002,
+} cal_properties_flag_e;
+
+typedef struct {
+       cal_record_create_cb create;
+       cal_record_destroy_cb destroy;
+       cal_record_clone_cb clone;
+       cal_record_get_str_cb get_str;
+       cal_record_get_str_p_cb get_str_p;
+       cal_record_get_int_cb get_int;
+       cal_record_get_double_cb get_double;
+       cal_record_get_lli_cb get_lli;
+       cal_record_get_caltime_cb get_caltime;
+       cal_record_set_str_cb set_str;
+       cal_record_set_int_cb set_int;
+       cal_record_set_double_cb set_double;
+       cal_record_set_lli_cb set_lli;
+       cal_record_set_caltime_cb set_caltime;
+       cal_record_add_child_record_cb add_child_record;
+       cal_record_remove_child_record_cb remove_child_record;
+       cal_record_get_child_record_count_cb get_child_record_count;
+       cal_record_get_child_record_at_p_cb get_child_record_at_p;
+       cal_record_clone_child_record_list_cb clone_child_record_list;
+} cal_record_plugin_cb_s;
+
+typedef struct {
+    cal_record_type_e type;
+    cal_record_plugin_cb_s *plugin_cb;
+    const char* view_uri;
+       unsigned int properties_max_count;
+       unsigned char *properties_flags;
+       unsigned char property_flag;
+} cal_record_s;
+
+#define CAL_RECORD_INIT_COMMON(common, intype, cb, uri) do {\
+    (common)->type = (intype);\
+    (common)->plugin_cb = (cb);\
+    (common)->view_uri = (uri);\
+    (common)->properties_max_count = 0;\
+    (common)->properties_flags = NULL;\
+    (common)->property_flag = 0;\
+} while (0)
+
+#define CAL_RECORD_COPY_COMMON(dst, src) do {\
+    (dst)->type = (src)->type;\
+    (dst)->plugin_cb = (src)->plugin_cb;\
+    (dst)->view_uri = (src)->view_uri;\
+    (dst)->properties_max_count = (src)->properties_max_count;\
+       if ((src)->properties_flags) \
+    {\
+        (dst)->properties_flags  = calloc((dst)->properties_max_count, sizeof(char));\
+            if ((dst)->properties_flags)\
+                memcpy((dst)->properties_flags,(src)->properties_flags,sizeof(char)*(dst)->properties_max_count);\
+    }\
+    (dst)->property_flag = (src)->property_flag;\
+} while (0)
+
+#define CAL_RECORD_RESET_COMMON(src) do {\
+    if ((src)->properties_flags) \
+    {\
+        free((src)->properties_flags); \
+        (src)->properties_max_count = 0;\
+        (src)->properties_flags = NULL;\
+        (src)->property_flag = 0;\
+    }\
+} while (0)
+
+cal_record_plugin_cb_s* _cal_record_get_plugin_cb(cal_record_type_e type);
+
+bool _cal_record_check_property_flag(calendar_record_h record, unsigned int property_id, cal_properties_flag_e flag);
+int _cal_record_set_projection(calendar_record_h record, const unsigned int *projection, const int projection_count, int properties_max_count);
+
+int _cal_record_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+int _cal_record_set_int( calendar_record_h record, unsigned int property_id, int value );
+int _cal_record_set_double( calendar_record_h record, unsigned int property_id, double value );
+int _cal_record_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+int _cal_record_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CALENDAR_SVC_RECORD_H__ */
+
diff --git a/common/cal_record_alarm.c b/common/cal_record_alarm.c
new file mode 100644 (file)
index 0000000..7098604
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>           //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_alarm_create( calendar_record_h* out_record );
+static int __cal_record_alarm_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_alarm_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_alarm_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_alarm_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_alarm_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_alarm_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value );
+static int __cal_record_alarm_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_alarm_set_int( calendar_record_h record, unsigned int property_id, int value );
+static int __cal_record_alarm_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+
+cal_record_plugin_cb_s _cal_record_alarm_plugin_cb = {
+       .create = __cal_record_alarm_create,
+       .destroy = __cal_record_alarm_destroy,
+       .clone = __cal_record_alarm_clone,
+       .get_str = __cal_record_alarm_get_str,
+       .get_str_p = __cal_record_alarm_get_str_p,
+       .get_int = __cal_record_alarm_get_int,
+       .get_double = NULL,
+       .get_lli = __cal_record_alarm_get_lli,
+       .get_caltime = NULL,
+       .set_str = __cal_record_alarm_set_str,
+       .set_int = __cal_record_alarm_set_int,
+       .set_double = NULL,
+       .set_lli = __cal_record_alarm_set_lli,
+       .set_caltime = 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 void __cal_record_alarm_struct_init(cal_alarm_s *record)
+{
+       memset(record,0,sizeof(cal_alarm_s));
+}
+
+static int __cal_record_alarm_create(calendar_record_h* out_record )
+{
+       cal_alarm_s *temp = NULL;
+       int ret= CALENDAR_ERROR_NONE, type = 0;
+
+       type = CAL_RECORD_TYPE_ALARM;
+
+       temp = (cal_alarm_s*)calloc(1,sizeof(cal_alarm_s));
+       retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_alarm_s:sch) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+       __cal_record_alarm_struct_init(temp);
+
+       *out_record = (calendar_record_h)temp;
+
+       return ret;
+}
+
+static void __cal_record_alarm_struct_free(cal_alarm_s *record)
+{
+       CAL_FREE(record->alarm_tone);
+       CAL_FREE(record->alarm_description);
+       CAL_FREE(record);
+}
+
+static int __cal_record_alarm_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_alarm_s *temp = (cal_alarm_s*)(record);
+
+    __cal_record_alarm_struct_free(temp);
+
+       return ret;
+}
+
+static int __cal_record_alarm_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+       cal_alarm_s *out_data = NULL;
+       cal_alarm_s *src_data = NULL;
+
+       src_data = (cal_alarm_s*)(record);
+
+       out_data = calloc(1, sizeof(cal_alarm_s));
+       retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_alarm_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+       CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+       out_data->alarm_id = src_data->alarm_id;
+       out_data->event_id = src_data->event_id;
+       out_data->alarm_type = src_data->alarm_type;
+       out_data->is_deleted = src_data->is_deleted;
+       out_data->alarm_time = src_data->alarm_time;
+       out_data->remind_tick = src_data->remind_tick;
+       out_data->remind_tick_unit = src_data->remind_tick_unit;
+       out_data->alarm_tone = SAFE_STRDUP(src_data->alarm_tone);
+       out_data->alarm_description = SAFE_STRDUP(src_data->alarm_description);
+
+    *out_record = (calendar_record_h)out_data;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_alarm_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_alarm_s *rec = (cal_alarm_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ALARM_TONE:
+               *out_str = SAFE_STRDUP(rec->alarm_tone);
+               break;
+       case CAL_PROPERTY_ALARM_DESCRIPTION:
+               *out_str = SAFE_STRDUP(rec->alarm_description);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_alarm_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_alarm_s *rec = (cal_alarm_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ALARM_TONE:
+               *out_str = (rec->alarm_tone);
+               break;
+       case CAL_PROPERTY_ALARM_DESCRIPTION:
+               *out_str = (rec->alarm_description);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_alarm_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+       cal_alarm_s *rec = (cal_alarm_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ALARM_TYPE:
+               *out_value = (rec->alarm_type);
+               break;
+       case CAL_PROPERTY_ALARM_TICK:
+               *out_value = (rec->remind_tick);
+               break;
+       case CAL_PROPERTY_ALARM_TICK_UNIT:
+               *out_value = (rec->remind_tick_unit);
+               break;
+       case CAL_PROPERTY_ALARM_ID:
+               *out_value = (rec->alarm_id);
+               break;
+       case CAL_PROPERTY_ALARM_EVENT_TODO_ID:
+           *out_value = (rec->event_id);
+           break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_alarm_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value )
+{
+       cal_alarm_s *rec = (cal_alarm_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ALARM_TIME:
+               *out_value = (rec->alarm_time);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_alarm_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+       cal_alarm_s *rec = (cal_alarm_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ALARM_TONE:
+               CAL_FREE(rec->alarm_tone);
+               rec->alarm_tone = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_ALARM_DESCRIPTION:
+               CAL_FREE(rec->alarm_description);
+               rec->alarm_description = SAFE_STRDUP(value);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_alarm_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+       cal_alarm_s *rec = (cal_alarm_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ALARM_TYPE:
+               (rec->alarm_type)=value;
+               break;
+       case CAL_PROPERTY_ALARM_TICK:
+               (rec->remind_tick)=value;
+               break;
+       case CAL_PROPERTY_ALARM_TICK_UNIT:
+               (rec->remind_tick_unit)=value;
+               break;
+       case CAL_PROPERTY_ALARM_ID:
+               (rec->alarm_id) = value;
+               break;
+    case CAL_PROPERTY_ALARM_EVENT_TODO_ID:
+        (rec->event_id) = value;
+        break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_alarm_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+       cal_alarm_s *rec = (cal_alarm_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ALARM_TIME:
+               (rec->alarm_time) = value;
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_attendee.c b/common/cal_record_attendee.c
new file mode 100644 (file)
index 0000000..f1a0da9
--- /dev/null
@@ -0,0 +1,311 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>           //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_attendee_create( calendar_record_h* out_record );
+static int __cal_record_attendee_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_attendee_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_attendee_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_attendee_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_attendee_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_attendee_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_attendee_set_int( calendar_record_h record, unsigned int property_id, int value );
+
+cal_record_plugin_cb_s _cal_record_attendee_plugin_cb = {
+       .create = __cal_record_attendee_create,
+       .destroy = __cal_record_attendee_destroy,
+       .clone = __cal_record_attendee_clone,
+       .get_str = __cal_record_attendee_get_str,
+       .get_str_p = __cal_record_attendee_get_str_p,
+       .get_int = __cal_record_attendee_get_int,
+       .get_double = NULL,
+       .get_lli = NULL,
+       .get_caltime = NULL,
+       .set_str = __cal_record_attendee_set_str,
+       .set_int = __cal_record_attendee_set_int,
+       .set_double = NULL,
+       .set_lli = NULL,
+       .set_caltime = 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 void __cal_record_attendee_struct_init(cal_attendee_s *record)
+{
+       memset(record,0,sizeof(cal_attendee_s));
+}
+
+static int __cal_record_attendee_create(calendar_record_h* out_record )
+{
+       cal_attendee_s *temp = NULL;
+       int ret= CALENDAR_ERROR_NONE, type = 0;
+
+       type = CAL_RECORD_TYPE_ATTENDEE;
+
+       temp = (cal_attendee_s*)calloc(1,sizeof(cal_attendee_s));
+       retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_attendee_s:sch) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+       __cal_record_attendee_struct_init(temp);
+
+    *out_record = (calendar_record_h)temp;
+
+       return ret;
+}
+
+static void __cal_record_attendee_struct_free(cal_attendee_s *record)
+{
+       CAL_FREE(record->attendee_number);
+       CAL_FREE(record->attendee_uid);
+       CAL_FREE(record->attendee_group);
+       CAL_FREE(record->attendee_email);
+       CAL_FREE(record->attendee_delegate_uri);
+       CAL_FREE(record->attendee_delegator_uri);
+       CAL_FREE(record->attendee_name);
+       CAL_FREE(record);
+}
+
+static int __cal_record_attendee_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_attendee_s *temp = (cal_attendee_s*)(record);
+
+    __cal_record_attendee_struct_free(temp);
+
+       return ret;
+}
+
+static int __cal_record_attendee_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+       cal_attendee_s *out_data = NULL;
+       cal_attendee_s *src_data = NULL;
+
+       src_data = (cal_attendee_s*)(record);
+
+       out_data = calloc(1, sizeof(cal_attendee_s));
+       retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_attendee_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+       CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+       out_data->event_id = src_data->event_id;
+       out_data->attendee_type = src_data->attendee_type;
+       out_data->attendee_ct_index = src_data->attendee_ct_index;
+       out_data->attendee_role = src_data->attendee_role;
+       out_data->attendee_status = src_data->attendee_status;
+       out_data->attendee_rsvp = src_data->attendee_rsvp;
+       out_data->attendee_number = SAFE_STRDUP(src_data->attendee_number);
+       out_data->attendee_uid = SAFE_STRDUP(src_data->attendee_uid);
+       out_data->attendee_group = SAFE_STRDUP(src_data->attendee_group);
+       out_data->attendee_email = SAFE_STRDUP(src_data->attendee_email);
+       out_data->attendee_delegate_uri = SAFE_STRDUP(src_data->attendee_delegate_uri);
+       out_data->attendee_delegator_uri = SAFE_STRDUP(src_data->attendee_delegator_uri);
+       out_data->attendee_name = SAFE_STRDUP(src_data->attendee_name);
+
+    *out_record = (calendar_record_h)out_data;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_attendee_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_attendee_s *rec = (cal_attendee_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ATTENDEE_NUMBER:
+               *out_str = SAFE_STRDUP(rec->attendee_number);
+               break;
+       case CAL_PROPERTY_ATTENDEE_UID:
+               *out_str = SAFE_STRDUP(rec->attendee_uid);
+               break;
+       case CAL_PROPERTY_ATTENDEE_GROUP:
+               *out_str = SAFE_STRDUP(rec->attendee_group);
+               break;
+       case CAL_PROPERTY_ATTENDEE_EMAIL:
+               *out_str = SAFE_STRDUP(rec->attendee_email);
+               break;
+       case CAL_PROPERTY_ATTENDEE_DELEGATE_URI:
+               *out_str = SAFE_STRDUP(rec->attendee_delegate_uri);
+               break;
+       case CAL_PROPERTY_ATTENDEE_DELEGATOR_URI:
+               *out_str = SAFE_STRDUP(rec->attendee_delegator_uri);
+               break;
+       case CAL_PROPERTY_ATTENDEE_NAME:
+               *out_str = SAFE_STRDUP(rec->attendee_name);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_attendee_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_attendee_s *rec = (cal_attendee_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ATTENDEE_NUMBER:
+               *out_str = (rec->attendee_number);
+               break;
+       case CAL_PROPERTY_ATTENDEE_UID:
+               *out_str = (rec->attendee_uid);
+               break;
+       case CAL_PROPERTY_ATTENDEE_GROUP:
+               *out_str = (rec->attendee_group);
+               break;
+       case CAL_PROPERTY_ATTENDEE_EMAIL:
+               *out_str = (rec->attendee_email);
+               break;
+       case CAL_PROPERTY_ATTENDEE_DELEGATE_URI:
+               *out_str = (rec->attendee_delegate_uri);
+               break;
+       case CAL_PROPERTY_ATTENDEE_DELEGATOR_URI:
+               *out_str = (rec->attendee_delegator_uri);
+               break;
+       case CAL_PROPERTY_ATTENDEE_NAME:
+               *out_str = (rec->attendee_name);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_attendee_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+       cal_attendee_s *rec = (cal_attendee_s*)(record);
+       switch( property_id )
+       {
+       //case CAL_PROPERTY_CALENDAR_ID:
+       //      *out_value = (rec->event_id);
+       //      break;
+       case CAL_PROPERTY_ATTENDEE_TYPE:
+               *out_value = (rec->attendee_type);
+               break;
+       case CAL_PROPERTY_ATTENDEE_CT_INDEX:
+               *out_value = (rec->attendee_ct_index);
+               break;
+       case CAL_PROPERTY_ATTENDEE_ROLE:
+               *out_value = (rec->attendee_role);
+               break;
+       case CAL_PROPERTY_ATTENDEE_STATUS:
+               *out_value = (rec->attendee_status);
+               break;
+       case CAL_PROPERTY_ATTENDEE_RSVP:
+               *out_value = (rec->attendee_rsvp);
+               break;
+       case CAL_PROPERTY_ATTENDEE_EVENT_ID:
+           *out_value = (rec->event_id);
+           break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_attendee_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+       cal_attendee_s *rec = (cal_attendee_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_ATTENDEE_NUMBER:
+               CAL_FREE(rec->attendee_number);
+               rec->attendee_number = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_ATTENDEE_UID:
+               CAL_FREE(rec->attendee_uid);
+               rec->attendee_uid = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_ATTENDEE_GROUP:
+               CAL_FREE(rec->attendee_group);
+               rec->attendee_group = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_ATTENDEE_EMAIL:
+               CAL_FREE(rec->attendee_email);
+               rec->attendee_email = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_ATTENDEE_DELEGATE_URI:
+               CAL_FREE(rec->attendee_delegate_uri);
+               rec->attendee_delegate_uri = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_ATTENDEE_DELEGATOR_URI:
+               CAL_FREE(rec->attendee_delegator_uri);
+               rec->attendee_delegator_uri = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_ATTENDEE_NAME:
+               CAL_FREE(rec->attendee_name);
+               rec->attendee_name = SAFE_STRDUP(value);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_attendee_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+       cal_attendee_s *rec = (cal_attendee_s*)(record);
+       switch( property_id )
+       {
+       //case CAL_PROPERTY_CALENDAR_ID:
+       //      *out_value = (rec->event_id);
+       //      break;
+       case CAL_PROPERTY_ATTENDEE_TYPE:
+               (rec->attendee_type) = value;
+               break;
+       case CAL_PROPERTY_ATTENDEE_CT_INDEX:
+               (rec->attendee_ct_index) = value;
+               break;
+       case CAL_PROPERTY_ATTENDEE_ROLE:
+               (rec->attendee_role) = value;
+               break;
+       case CAL_PROPERTY_ATTENDEE_STATUS:
+               (rec->attendee_status) = value;
+               break;
+       case CAL_PROPERTY_ATTENDEE_RSVP:
+               (rec->attendee_rsvp) = value;
+               break;
+    case CAL_PROPERTY_ATTENDEE_EVENT_ID:
+        (rec->event_id) = value;
+        break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_calendar.c b/common/cal_record_calendar.c
new file mode 100644 (file)
index 0000000..5694ad8
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>           //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_calendar_create( calendar_record_h* out_record );
+static int __cal_record_calendar_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_calendar_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_calendar_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_calendar_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_calendar_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_calendar_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_calendar_set_int( calendar_record_h record, unsigned int property_id, int value );
+
+cal_record_plugin_cb_s _cal_record_calendar_plugin_cb = {
+       .create = __cal_record_calendar_create,
+       .destroy = __cal_record_calendar_destroy,
+       .clone = __cal_record_calendar_clone,
+       .get_str = __cal_record_calendar_get_str,
+       .get_str_p = __cal_record_calendar_get_str_p,
+       .get_int = __cal_record_calendar_get_int,
+       .get_double = NULL,
+       .get_lli = NULL,
+       .get_caltime = NULL,
+       .set_str = __cal_record_calendar_set_str,
+       .set_int = __cal_record_calendar_set_int,
+       .set_double = NULL,
+       .set_lli = NULL,
+       .set_caltime = 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 void __cal_record_calendar_struct_init(cal_calendar_s *record)
+{
+       memset(record,0,sizeof(cal_calendar_s));
+       record->index = -1;
+       record->visibility = true;
+       record->account_id = LOCAL_ACCOUNT_ID;
+       record->sync_event = 1;
+}
+
+static int __cal_record_calendar_create( calendar_record_h* out_record )
+{
+       cal_calendar_s *temp = NULL;
+       int ret= CALENDAR_ERROR_NONE, type = 0;
+
+       type = CAL_RECORD_TYPE_CALENDAR;
+
+       temp = (cal_calendar_s*)calloc(1,sizeof(cal_calendar_s));
+       retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_calendar_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+       __cal_record_calendar_struct_init(temp);
+
+       *out_record = (calendar_record_h)temp;
+
+       return ret;
+}
+
+static void __cal_record_calendar_struct_free(cal_calendar_s *record)
+{
+       CAL_FREE(record->uid);
+       CAL_FREE(record->name);
+       CAL_FREE(record->description);
+       CAL_FREE(record->color);
+       CAL_FREE(record->location);
+       CAL_FREE(record->sync_data1);
+       CAL_FREE(record->sync_data2);
+       CAL_FREE(record->sync_data3);
+       CAL_FREE(record->sync_data4);
+       CAL_FREE(record);
+}
+
+static int __cal_record_calendar_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+       cal_calendar_s *temp = (cal_calendar_s*)(record);
+
+    __cal_record_calendar_struct_free(temp);
+
+    return ret;
+}
+
+static int __cal_record_calendar_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+       cal_calendar_s *out_data = NULL;
+       cal_calendar_s *src_data = NULL;
+
+       src_data = (cal_calendar_s*)(record);
+
+       out_data = calloc(1, sizeof(cal_calendar_s));
+       retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_calendar_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+
+       CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+       out_data->index = src_data->index;
+       out_data->store_type = src_data->store_type;
+       out_data->uid = SAFE_STRDUP(src_data->uid);
+       out_data->updated = src_data->updated;
+       out_data->name = SAFE_STRDUP(src_data->name);
+       out_data->description = SAFE_STRDUP(src_data->description);
+       out_data->color = SAFE_STRDUP(src_data->color);
+       out_data->location = SAFE_STRDUP(src_data->location);
+       out_data->visibility = src_data->visibility;
+       out_data->sync_event = src_data->sync_event;
+       out_data->is_deleted = src_data->is_deleted;
+       out_data->account_id = src_data->account_id;
+       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);
+
+    *out_record = (calendar_record_h)out_data;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_calendar_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_calendar_s *cal_rec = (cal_calendar_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_CALENDAR_UID:
+               *out_str = SAFE_STRDUP(cal_rec->uid);
+               break;
+       case CAL_PROPERTY_CALENDAR_NAME:
+               *out_str = SAFE_STRDUP(cal_rec->name);
+               break;
+       case CAL_PROPERTY_CALENDAR_DESCRIPTION:
+               *out_str = SAFE_STRDUP(cal_rec->description);
+               break;
+       case CAL_PROPERTY_CALENDAR_COLOR:
+               *out_str = SAFE_STRDUP(cal_rec->color);
+               break;
+       case CAL_PROPERTY_CALENDAR_LOCATION:
+               *out_str = SAFE_STRDUP(cal_rec->location);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA1:
+               *out_str = SAFE_STRDUP(cal_rec->sync_data1);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA2:
+               *out_str = SAFE_STRDUP(cal_rec->sync_data2);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA3:
+               *out_str = SAFE_STRDUP(cal_rec->sync_data3);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA4:
+               *out_str = SAFE_STRDUP(cal_rec->sync_data4);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_calendar_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_calendar_s *cal_rec = (cal_calendar_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_CALENDAR_UID:
+               *out_str = (cal_rec->uid);
+               break;
+       case CAL_PROPERTY_CALENDAR_NAME:
+               *out_str = (cal_rec->name);
+               break;
+       case CAL_PROPERTY_CALENDAR_DESCRIPTION:
+               *out_str = (cal_rec->description);
+               break;
+       case CAL_PROPERTY_CALENDAR_COLOR:
+               *out_str = (cal_rec->color);
+               break;
+       case CAL_PROPERTY_CALENDAR_LOCATION:
+               *out_str = (cal_rec->location);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA1:
+               *out_str = (cal_rec->sync_data1);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA2:
+               *out_str = (cal_rec->sync_data2);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA3:
+               *out_str = (cal_rec->sync_data3);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA4:
+               *out_str = (cal_rec->sync_data4);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_calendar_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+       cal_calendar_s *cal_rec = (cal_calendar_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_CALENDAR_ID:
+               *out_value = (cal_rec->index);
+               break;
+       case CAL_PROPERTY_CALENDAR_VISIBILITY:
+               *out_value = (cal_rec->visibility);
+               break;
+       case CAL_PROPERTY_CALENDAR_IS_DELETED:
+               *out_value = (cal_rec->is_deleted);
+               break;
+       case CAL_PROPERTY_CALENDAR_ACCOUNT_ID:
+               *out_value = (cal_rec->account_id);
+               break;
+       case CAL_PROPERTY_CALENDAR_STORE_TYPE:
+               *out_value = (cal_rec->store_type);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_EVENT:
+           *out_value = (cal_rec->sync_event);
+           break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_calendar_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+       cal_calendar_s *cal_rec = (cal_calendar_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_CALENDAR_UID:
+               CAL_FREE(cal_rec->uid);
+               cal_rec->uid = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_NAME:
+               CAL_FREE(cal_rec->name);
+               cal_rec->name = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_DESCRIPTION:
+               CAL_FREE(cal_rec->description);
+               cal_rec->description = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_COLOR:
+               CAL_FREE(cal_rec->color);
+               cal_rec->color = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_LOCATION:
+               CAL_FREE(cal_rec->location);
+               cal_rec->location = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA1:
+               CAL_FREE(cal_rec->sync_data1);
+               cal_rec->sync_data1 = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA2:
+               CAL_FREE(cal_rec->sync_data2);
+               cal_rec->sync_data2 = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA3:
+               CAL_FREE(cal_rec->sync_data3);
+               cal_rec->sync_data3 = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_CALENDAR_SYNC_DATA4:
+               CAL_FREE(cal_rec->sync_data4);
+               cal_rec->sync_data4 = SAFE_STRDUP(value);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_calendar_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+       cal_calendar_s *cal_rec = (cal_calendar_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_CALENDAR_ID:
+               (cal_rec->index) = value;
+               break;
+       case CAL_PROPERTY_CALENDAR_VISIBILITY:
+               (cal_rec->visibility) = value;
+               break;
+       case CAL_PROPERTY_CALENDAR_IS_DELETED:
+               (cal_rec->is_deleted) = value;
+               break;
+       case CAL_PROPERTY_CALENDAR_ACCOUNT_ID:
+               (cal_rec->account_id) = value;
+               break;
+       case CAL_PROPERTY_CALENDAR_STORE_TYPE:
+               (cal_rec->store_type) = value;
+               break;
+    case CAL_PROPERTY_CALENDAR_SYNC_EVENT:
+        (cal_rec->sync_event) = value;
+        break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_event.c b/common/cal_record_event.c
new file mode 100644 (file)
index 0000000..ced7937
--- /dev/null
@@ -0,0 +1,1422 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>           //bool
+#include <string.h>
+
+#include "calendar_list.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_event_create( calendar_record_h* out_record );
+static int __cal_record_event_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_event_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_event_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_event_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_event_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_event_get_double( calendar_record_h record, unsigned int property_id, double* out_value );
+static int __cal_record_event_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value );
+static int __cal_record_event_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value );
+static int __cal_record_event_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_event_set_int( calendar_record_h record, unsigned int property_id, int value );
+static int __cal_record_event_set_double( calendar_record_h record, unsigned int property_id, double value );
+static int __cal_record_event_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+static int __cal_record_event_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value );
+static int __cal_record_event_add_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record );
+static int __cal_record_event_remove_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record );
+static int __cal_record_event_get_child_record_count( calendar_record_h record, unsigned int property_id, unsigned int* count  );
+static int __cal_record_event_get_child_record_at_p( calendar_record_h record, unsigned int property_id, int index, calendar_record_h* child_record );
+static int __cal_record_event_clone_child_record_list( calendar_record_h record, unsigned int property_id, calendar_list_h* out_list );
+
+cal_record_plugin_cb_s _cal_record_event_plugin_cb = {
+    .create = __cal_record_event_create,
+    .destroy = __cal_record_event_destroy,
+    .clone = __cal_record_event_clone,
+    .get_str = __cal_record_event_get_str,
+    .get_str_p = __cal_record_event_get_str_p,
+    .get_int = __cal_record_event_get_int,
+    .get_double = __cal_record_event_get_double,
+    .get_lli = __cal_record_event_get_lli,
+    .get_caltime = __cal_record_event_get_caltime,
+    .set_str = __cal_record_event_set_str,
+    .set_int = __cal_record_event_set_int,
+    .set_double = __cal_record_event_set_double,
+    .set_lli = __cal_record_event_set_lli,
+    .set_caltime = __cal_record_event_set_caltime,
+    .add_child_record = __cal_record_event_add_child_record,
+    .remove_child_record = __cal_record_event_remove_child_record,
+    .get_child_record_count = __cal_record_event_get_child_record_count,
+    .get_child_record_at_p = __cal_record_event_get_child_record_at_p,
+    .clone_child_record_list = __cal_record_event_clone_child_record_list
+};
+
+static void __cal_record_event_struct_init(cal_event_s *record)
+{
+    memset(record,0,sizeof(cal_event_s));
+
+    record->meeting_status = CALENDAR_EVENT_STATUS_NONE;
+    record->calendar_id = DEFAULT_EVENT_CALENDAR_BOOK_ID;
+
+    record->index = CAL_INVALID_ID;
+    record->timezone = 0;
+    record->contact_id = CAL_INVALID_ID;
+    record->attendee_list = NULL;
+    record->busy_status = 2;
+    record->summary = NULL;
+    record->description = NULL;
+    record->location= NULL;
+    record->categories = NULL;
+    record->exdate = NULL;
+    record->organizer_email = NULL;
+    record->organizer_name = NULL;
+    record->uid= NULL;
+    record->original_event_id = CAL_INVALID_ID;
+       record->event_status = CALENDAR_EVENT_STATUS_NONE;
+
+    record->is_deleted = 0;
+    record->latitude = CALENDAR_RECORD_NO_COORDINATE; // set default 1000 out of range(-180 ~ 180)
+    record->longitude = CALENDAR_RECORD_NO_COORDINATE; // set default 1000 out of range(-180 ~ 180)
+    record->freq = CALENDAR_RECURRENCE_NONE;
+       record->wkst = CALENDAR_SUNDAY;
+    record->until_utime = CALENDAR_RECORD_NO_UNTIL;
+
+    return ;
+}
+
+static int __cal_record_event_create( calendar_record_h* out_record )
+{
+    cal_event_s *temp = NULL;
+    int ret= CALENDAR_ERROR_NONE, type = 0;
+
+    type = CAL_RECORD_TYPE_EVENT;
+
+    temp = (cal_event_s*)calloc(1, sizeof(cal_event_s));
+    retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_event_s:sch) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    __cal_record_event_struct_init(temp);
+
+    *out_record = (calendar_record_h)temp;
+
+    return ret;
+}
+
+static void __cal_record_event_struct_free(cal_event_s *record, bool delete_child)
+{
+    CAL_FREE(record->summary);
+    CAL_FREE(record->description);
+    CAL_FREE(record->location);
+    CAL_FREE(record->categories);
+    CAL_FREE(record->exdate);
+    CAL_FREE(record->uid);
+    CAL_FREE(record->organizer_name);
+    CAL_FREE(record->organizer_email);
+    CAL_FREE(record->start_tzid);
+    CAL_FREE(record->end_tzid);
+
+    CAL_FREE(record->bysecond);
+    CAL_FREE(record->byminute);
+    CAL_FREE(record->byhour);
+    CAL_FREE(record->byday);
+    CAL_FREE(record->bymonthday);
+    CAL_FREE(record->byyearday);
+    CAL_FREE(record->byweekno);
+    CAL_FREE(record->bymonth);
+    CAL_FREE(record->bysetpos);
+
+    CAL_FREE(record->recurrence_id);
+    CAL_FREE(record->rdate);
+    CAL_FREE(record->sync_data1);
+    CAL_FREE(record->sync_data2);
+    CAL_FREE(record->sync_data3);
+    CAL_FREE(record->sync_data4);
+
+    if (delete_child == true)
+    {
+        if ( record->alarm_list )
+        {
+            GList *alarm_list = g_list_first(record->alarm_list);
+            calendar_record_h alarm_child_record = NULL;
+            while (alarm_list)
+            {
+                alarm_child_record = (calendar_record_h)alarm_list->data;
+                if (alarm_child_record == NULL)
+                {
+                    alarm_list = g_list_next(alarm_list);
+                    continue;
+                }
+
+                calendar_record_destroy(alarm_child_record, true);
+
+                alarm_list = g_list_next(alarm_list);
+            }
+            g_list_free(record->alarm_list);
+            record->alarm_list = NULL;
+        }
+
+        if( record->attendee_list )
+        {
+            GList * attendee_list = g_list_first(record->attendee_list);
+            calendar_record_h attendee = NULL;
+
+            while (attendee_list)
+            {
+                attendee = (calendar_record_h)attendee_list->data;
+                if (attendee == NULL)
+                {
+                    attendee_list = g_list_next(attendee_list);
+                    continue;
+                }
+
+                calendar_record_destroy(attendee, true);
+
+                attendee_list = g_list_next(attendee_list);
+            }
+            g_list_free(record->attendee_list);
+            record->attendee_list = NULL;
+        }
+        if( record->exception_list )
+        {
+            GList * exception_list = g_list_first(record->exception_list);
+            calendar_record_h exception = NULL;
+
+            while (exception_list)
+            {
+                exception = (calendar_record_h)exception_list->data;
+                if (exception == NULL)
+                {
+                    exception_list = g_list_next(exception_list);
+                    continue;
+                }
+
+                calendar_record_destroy(exception, true);
+
+                exception_list = g_list_next(exception_list);
+            }
+            g_list_free(record->exception_list);
+            record->exception_list = NULL;
+        }
+        if( record->extended_list )
+        {
+            GList * extended_list = g_list_first(record->extended_list);
+            calendar_record_h extended = NULL;
+
+            while (extended_list)
+            {
+                extended = (calendar_record_h)extended_list->data;
+                if (extended == NULL)
+                {
+                    extended_list = g_list_next(extended_list);
+                    continue;
+                }
+
+                calendar_record_destroy(extended, true);
+
+                extended_list = g_list_next(extended_list);
+            }
+            g_list_free(record->extended_list);
+            record->extended_list = NULL;
+        }
+    }
+
+    CAL_FREE(record);
+}
+
+static int __cal_record_event_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_event_s *temp = (cal_event_s*)(record);
+
+   __cal_record_event_struct_free(temp, delete_child);
+
+    return ret;
+}
+
+static int __cal_record_event_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+    cal_event_s *out_data = NULL;
+    cal_event_s *src_data = NULL;
+
+    src_data = (cal_event_s*)(record);
+
+    out_data = calloc(1, sizeof(cal_event_s));
+    retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_event_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+    out_data->index = src_data->index;
+    out_data->calendar_id = src_data->calendar_id;
+
+    out_data->summary = SAFE_STRDUP(src_data->summary);
+    out_data->description = SAFE_STRDUP(src_data->description);
+    out_data->location = SAFE_STRDUP(src_data->location);
+    out_data->categories = SAFE_STRDUP(src_data->categories);
+    out_data->exdate = SAFE_STRDUP(src_data->exdate);
+
+    out_data->event_status = src_data->event_status;
+    out_data->priority = src_data->priority;
+    out_data->timezone = src_data->timezone;
+    out_data->contact_id = src_data->contact_id;
+    out_data->busy_status = src_data->busy_status;
+    out_data->sensitivity = src_data->sensitivity;
+    out_data->meeting_status = src_data->meeting_status;
+
+    out_data->uid = SAFE_STRDUP(src_data->uid);
+    out_data->organizer_name = SAFE_STRDUP(src_data->organizer_name);
+    out_data->organizer_email = SAFE_STRDUP(src_data->organizer_email);
+
+    out_data->original_event_id = src_data->original_event_id;
+    out_data->latitude = src_data->latitude;
+    out_data->longitude = src_data->longitude;
+    out_data->email_id = src_data->email_id;
+    //out_data->availability = src_data->availability;
+    out_data->created_time = src_data->created_time;
+    //out_data->completed_time = src_data->completed_time;
+    //out_data->progress = src_data->progress;
+    out_data->is_deleted = src_data->is_deleted;
+    //out_data->duration = src_data->duration;
+    out_data->last_mod = src_data->last_mod;
+    //out_data->has_rrule = src_data->has_rrule;
+    out_data->freq = src_data->freq;
+    out_data->range_type = src_data->range_type;
+    out_data->until_type = src_data->until_type;
+    out_data->until_utime = src_data->until_utime;
+    out_data->until_year = src_data->until_year;
+    out_data->until_month = src_data->until_month;
+    out_data->until_mday = src_data->until_mday;
+    out_data->count = src_data->count;
+    out_data->interval = src_data->interval;
+    out_data->bysecond = SAFE_STRDUP(src_data->bysecond);
+    out_data->byminute = SAFE_STRDUP(src_data->byminute);
+    out_data->byhour = SAFE_STRDUP(src_data->byhour);
+    out_data->byday = SAFE_STRDUP(src_data->byday);
+    out_data->bymonthday = SAFE_STRDUP(src_data->bymonthday);
+    out_data->byyearday = SAFE_STRDUP(src_data->byyearday);
+    out_data->byweekno = SAFE_STRDUP(src_data->byweekno);
+    out_data->bymonth = SAFE_STRDUP(src_data->bymonth);
+    out_data->bysetpos = SAFE_STRDUP(src_data->bysetpos);
+    out_data->wkst = src_data->wkst;
+    out_data->recurrence_id = SAFE_STRDUP(src_data->recurrence_id);
+    out_data->rdate = SAFE_STRDUP(src_data->rdate);
+    out_data->has_attendee = src_data->has_attendee;
+    out_data->has_alarm = src_data->has_alarm;
+    out_data->system_type = src_data->system_type;
+    out_data->updated = src_data->updated;
+
+    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);
+
+    out_data->start = src_data->start;
+    out_data->start_tzid = SAFE_STRDUP(src_data->start_tzid);
+    out_data->end = src_data->end;
+    out_data->end_tzid = SAFE_STRDUP(src_data->end_tzid);
+
+    if( src_data->alarm_list )
+    {
+        GList *alarm_list = g_list_first(src_data->alarm_list);
+        calendar_record_h alarm_child_record;
+
+        while (alarm_list)
+        {
+            calendar_record_h child_clone = NULL;
+            alarm_child_record = (calendar_record_h)alarm_list->data;
+            if (alarm_child_record == NULL)
+            {
+                alarm_list = g_list_next(alarm_list);
+                continue;
+            }
+            if (calendar_record_clone(alarm_child_record, &child_clone) == CALENDAR_ERROR_NONE)
+            {
+
+                calendar_record_add_child_record((calendar_record_h)out_data,
+                        CAL_PROPERTY_EVENT_CALENDAR_ALARM,child_clone);
+
+            }
+                       alarm_list = g_list_next(alarm_list);
+        }
+
+    }
+
+    if( src_data->attendee_list )
+    {
+        GList * attendee_list = src_data->attendee_list;
+        calendar_record_h attendee_child = NULL;
+
+        while (attendee_list)
+        {
+            calendar_record_h child_clone = NULL;
+            attendee_child = (calendar_record_h)attendee_list->data;
+            if (attendee_child == NULL)
+            {
+                attendee_list = g_list_next(attendee_list);
+                continue;
+            }
+            if (calendar_record_clone(attendee_child, &child_clone) == CALENDAR_ERROR_NONE)
+            {
+
+                calendar_record_add_child_record((calendar_record_h)out_data,
+                        CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE,child_clone);
+
+            }
+                       attendee_list = g_list_next(attendee_list);
+        }
+
+    }
+
+    if( src_data->exception_list )
+    {
+        GList * exception_list = src_data->exception_list;
+        calendar_record_h exception = NULL;
+
+        while (exception_list)
+        {
+            calendar_record_h child_clone = NULL;
+            exception = (calendar_record_h)exception_list->data;
+            if (exception == NULL)
+            {
+                exception_list = g_list_next(exception_list);
+                continue;
+            }
+            if (calendar_record_clone(exception, &child_clone) == CALENDAR_ERROR_NONE)
+            {
+
+                calendar_record_add_child_record((calendar_record_h)out_data,
+                        CAL_PROPERTY_EVENT_EXCEPTION,child_clone);
+
+            }
+            exception_list = g_list_next(exception_list);
+        }
+
+    }
+
+    if( src_data->extended_list )
+    {
+        GList * extended_list = src_data->extended_list;
+        calendar_record_h extended = NULL;
+
+        while (extended_list)
+        {
+            calendar_record_h child_clone = NULL;
+            extended = (calendar_record_h)extended_list->data;
+            if (extended == NULL)
+            {
+                extended_list = g_list_next(extended_list);
+                continue;
+            }
+            if (calendar_record_clone(extended, &child_clone) == CALENDAR_ERROR_NONE)
+            {
+
+                calendar_record_add_child_record((calendar_record_h)out_data,
+                        CAL_PROPERTY_EVENT_EXTENDED,child_clone);
+
+            }
+            extended_list = g_list_next(extended_list);
+        }
+
+    }
+
+    *out_record = (calendar_record_h)out_data;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_SUMMARY:
+        *out_str = SAFE_STRDUP(rec->summary);
+        break;
+    case CAL_PROPERTY_EVENT_DESCRIPTION:
+        *out_str = SAFE_STRDUP(rec->description);
+        break;
+    case CAL_PROPERTY_EVENT_LOCATION:
+        *out_str = SAFE_STRDUP(rec->location);
+        break;
+    case CAL_PROPERTY_EVENT_CATEGORIES:
+        *out_str = SAFE_STRDUP(rec->categories);
+        break;
+    case CAL_PROPERTY_EVENT_EXDATE:
+        *out_str = SAFE_STRDUP(rec->exdate);
+        break;
+    case CAL_PROPERTY_EVENT_UID:
+        *out_str = SAFE_STRDUP(rec->uid);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_NAME:
+        *out_str = SAFE_STRDUP(rec->organizer_name);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_EMAIL:
+        *out_str = SAFE_STRDUP(rec->organizer_email);
+        break;
+    case CAL_PROPERTY_EVENT_BYSECOND:
+        *out_str = SAFE_STRDUP(rec->bysecond);
+        break;
+    case CAL_PROPERTY_EVENT_BYMINUTE:
+        *out_str = SAFE_STRDUP(rec->byminute);
+        break;
+    case CAL_PROPERTY_EVENT_BYHOUR:
+        *out_str = SAFE_STRDUP(rec->byhour);
+        break;
+    case CAL_PROPERTY_EVENT_BYDAY:
+        *out_str = SAFE_STRDUP(rec->byday);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTHDAY:
+        *out_str = SAFE_STRDUP(rec->bymonthday);
+        break;
+    case CAL_PROPERTY_EVENT_BYYEARDAY:
+        *out_str = SAFE_STRDUP(rec->byyearday);
+        break;
+    case CAL_PROPERTY_EVENT_BYWEEKNO:
+        *out_str = SAFE_STRDUP(rec->byweekno);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTH:
+        *out_str = SAFE_STRDUP(rec->bymonth);
+        break;
+    case CAL_PROPERTY_EVENT_BYSETPOS:
+        *out_str = SAFE_STRDUP(rec->bysetpos);
+        break;
+    case CAL_PROPERTY_EVENT_RECURRENCE_ID:
+        *out_str = SAFE_STRDUP(rec->recurrence_id);
+        break;
+    case CAL_PROPERTY_EVENT_RDATE:
+        *out_str = SAFE_STRDUP(rec->rdate);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA1:
+        *out_str = SAFE_STRDUP(rec->sync_data1);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA2:
+        *out_str = SAFE_STRDUP(rec->sync_data2);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA3:
+        *out_str = SAFE_STRDUP(rec->sync_data3);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA4:
+        *out_str = SAFE_STRDUP(rec->sync_data4);
+        break;
+    case CAL_PROPERTY_EVENT_START_TZID:
+        *out_str = SAFE_STRDUP(rec->start_tzid);
+        break;
+    case CAL_PROPERTY_EVENT_END_TZID:
+        *out_str = SAFE_STRDUP(rec->end_tzid);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_SUMMARY:
+        *out_str = (rec->summary);
+        break;
+    case CAL_PROPERTY_EVENT_DESCRIPTION:
+        *out_str = (rec->description);
+        break;
+    case CAL_PROPERTY_EVENT_LOCATION:
+        *out_str = (rec->location);
+        break;
+    case CAL_PROPERTY_EVENT_CATEGORIES:
+        *out_str = (rec->categories);
+        break;
+    case CAL_PROPERTY_EVENT_EXDATE:
+        *out_str = (rec->exdate);
+        break;
+    case CAL_PROPERTY_EVENT_UID:
+        *out_str = (rec->uid);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_NAME:
+        *out_str = (rec->organizer_name);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_EMAIL:
+        *out_str = (rec->organizer_email);
+        break;
+    case CAL_PROPERTY_EVENT_BYSECOND:
+        *out_str = (rec->bysecond);
+        break;
+    case CAL_PROPERTY_EVENT_BYMINUTE:
+        *out_str = (rec->byminute);
+        break;
+    case CAL_PROPERTY_EVENT_BYHOUR:
+        *out_str = (rec->byhour);
+        break;
+    case CAL_PROPERTY_EVENT_BYDAY:
+        *out_str = (rec->byday);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTHDAY:
+        *out_str = (rec->bymonthday);
+        break;
+    case CAL_PROPERTY_EVENT_BYYEARDAY:
+        *out_str = (rec->byyearday);
+        break;
+    case CAL_PROPERTY_EVENT_BYWEEKNO:
+        *out_str = (rec->byweekno);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTH:
+        *out_str = (rec->bymonth);
+        break;
+    case CAL_PROPERTY_EVENT_BYSETPOS:
+        *out_str = (rec->bysetpos);
+        break;
+    case CAL_PROPERTY_EVENT_RECURRENCE_ID:
+        *out_str = (rec->recurrence_id);
+        break;
+    case CAL_PROPERTY_EVENT_RDATE:
+        *out_str = (rec->rdate);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA1:
+        *out_str = (rec->sync_data1);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA2:
+        *out_str = (rec->sync_data2);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA3:
+        *out_str = (rec->sync_data3);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA4:
+        *out_str = (rec->sync_data4);
+        break;
+    case CAL_PROPERTY_EVENT_START_TZID:
+        *out_str = (rec->start_tzid);
+        break;
+    case CAL_PROPERTY_EVENT_END_TZID:
+        *out_str = (rec->end_tzid);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_ID:
+        *out_value = (rec->index);
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_ID:
+        *out_value = (rec->calendar_id);
+        break;
+    case CAL_PROPERTY_EVENT_EVENT_STATUS:
+        *out_value = (rec->event_status);
+        break;
+    //priority
+    case CAL_PROPERTY_EVENT_PRIORITY:
+        *out_value = (rec->priority);
+        break;
+    //timezone
+    case CAL_PROPERTY_EVENT_TIMEZONE:
+        *out_value = (rec->timezone);
+        break;
+    //contact_id
+    case CAL_PROPERTY_EVENT_CONTACT_ID:
+        *out_value = (rec->contact_id);
+        break;
+    //busy_status
+    case CAL_PROPERTY_EVENT_BUSY_STATUS:
+        *out_value = (rec->busy_status);
+        break;
+    //sensitivity
+    case CAL_PROPERTY_EVENT_SENSITIVITY:
+        *out_value = (rec->sensitivity);
+        break;
+    //meeting_status
+    case CAL_PROPERTY_EVENT_MEETING_STATUS:
+        *out_value = (rec->meeting_status);
+        break;
+    //original_event_id
+    case CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID:
+        *out_value = (rec->original_event_id);
+        break;
+    //email_id
+    case CAL_PROPERTY_EVENT_EMAIL_ID:
+        *out_value = (rec->email_id);
+        break;
+    //is_deleted
+    case CAL_PROPERTY_EVENT_IS_DELETED:
+        *out_value = (rec->is_deleted);
+        break;
+    //freq
+    case CAL_PROPERTY_EVENT_FREQ:
+        *out_value = (rec->freq);
+        break;
+    //range_type
+    case CAL_PROPERTY_EVENT_RANGE_TYPE:
+        *out_value = (rec->range_type);
+        break;
+    //count
+    case CAL_PROPERTY_EVENT_COUNT:
+        *out_value = (rec->count);
+        break;
+    //interval
+    case CAL_PROPERTY_EVENT_INTERVAL:
+        *out_value = (rec->interval);
+        break;
+    //wkst
+    case CAL_PROPERTY_EVENT_WKST:
+        *out_value = (rec->wkst);
+        break;
+    //has_attendee
+    case CAL_PROPERTY_EVENT_HAS_ATTENDEE:
+        *out_value = (rec->has_attendee);
+        break;
+    //has_alarm
+    case CAL_PROPERTY_EVENT_HAS_ALARM:
+        *out_value = (rec->has_alarm);
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE:
+        *out_value = (rec->system_type);
+        break;
+    case CAL_PROPERTY_EVENT_IS_ALLDAY:
+        *out_value = (rec->start.type);
+        break;
+    default:
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_double( calendar_record_h record, unsigned int property_id, double* out_value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_LATITUDE:
+        *out_value = (rec->latitude);
+        break;
+    case CAL_PROPERTY_EVENT_LONGITUDE:
+        *out_value = (rec->longitude);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_CREATED_TIME:
+        *out_value = (rec->created_time);
+        break;
+    case CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME:
+        *out_value = (rec->last_mod);
+        break;
+    default:
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_START:
+        *out_value = rec->start;
+        break;
+    case CAL_PROPERTY_EVENT_END:
+        *out_value = rec->end;
+        break;
+    case CAL_PROPERTY_EVENT_UNTIL:
+        if (rec->until_type == CALENDAR_TIME_UTIME)
+        {
+            CAL_CALTIME_SET_UTIME(*out_value, rec->until_utime);
+        }
+        else
+        {
+            CAL_CALTIME_SET_DATE(*out_value, rec->until_year,rec->until_month,rec->until_mday);
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_SUMMARY:
+        CAL_FREE(rec->summary);
+        rec->summary = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_DESCRIPTION:
+        CAL_FREE(rec->description);
+        rec->description = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_LOCATION:
+        CAL_FREE(rec->location);
+        rec->location = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_CATEGORIES:
+        CAL_FREE(rec->categories);
+        rec->categories = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_EXDATE:
+        CAL_FREE(rec->exdate);
+        rec->exdate = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_UID:
+        CAL_FREE(rec->uid);
+        rec->uid = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_NAME:
+        CAL_FREE(rec->organizer_name);
+        rec->organizer_name = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_EMAIL:
+        CAL_FREE(rec->organizer_email);
+        rec->organizer_email = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYSECOND:
+        CAL_FREE(rec->bysecond);
+        rec->bysecond = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYMINUTE:
+        CAL_FREE(rec->byminute);
+        rec->byminute = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYHOUR:
+        CAL_FREE(rec->byhour);
+        rec->byhour = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYDAY:
+        CAL_FREE(rec->byday);
+        rec->byday = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTHDAY:
+        CAL_FREE(rec->bymonthday);
+        rec->bymonthday = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYYEARDAY:
+        CAL_FREE(rec->byyearday);
+        rec->byyearday = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYWEEKNO:
+        CAL_FREE(rec->byweekno);
+        rec->byweekno = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTH:
+        CAL_FREE(rec->bymonth);
+        rec->bymonth = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_BYSETPOS:
+        CAL_FREE(rec->bysetpos);
+        rec->bysetpos = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_RECURRENCE_ID:
+        CAL_FREE(rec->recurrence_id);
+        rec->recurrence_id = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_RDATE:
+        CAL_FREE(rec->rdate);
+        rec->rdate = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA1:
+        CAL_FREE(rec->sync_data1);
+        rec->sync_data1 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA2:
+        CAL_FREE(rec->sync_data2);
+        rec->sync_data2 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA3:
+        CAL_FREE(rec->sync_data3);
+        rec->sync_data3 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA4:
+        CAL_FREE(rec->sync_data4);
+        rec->sync_data4 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_START_TZID:
+        CAL_FREE(rec->start_tzid);
+        rec->start_tzid = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EVENT_END_TZID:
+        CAL_FREE(rec->end_tzid);
+        rec->end_tzid = SAFE_STRDUP(value);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_ID:
+        (rec->index) = value;
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_ID:
+        (rec->calendar_id) = value;
+        break;
+    case CAL_PROPERTY_EVENT_EVENT_STATUS:
+               switch (value)
+               {
+               case CALENDAR_EVENT_STATUS_NONE:
+               case CALENDAR_EVENT_STATUS_TENTATIVE:
+               case CALENDAR_EVENT_STATUS_CONFIRMED:
+               case CALENDAR_EVENT_STATUS_CANCELLED:
+                       (rec->event_status) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               break;
+    //priority
+    case CAL_PROPERTY_EVENT_PRIORITY:
+        (rec->priority) = value;
+        break;
+    //timezone
+    case CAL_PROPERTY_EVENT_TIMEZONE:
+        (rec->timezone) = value;
+        break;
+    //contact_id
+    case CAL_PROPERTY_EVENT_CONTACT_ID:
+        (rec->contact_id) = value;
+        break;
+    //busy_status
+    case CAL_PROPERTY_EVENT_BUSY_STATUS:
+               switch (value)
+               {
+               case CALENDAR_EVENT_BUSY_STATUS_FREE:
+               case CALENDAR_EVENT_BUSY_STATUS_BUSY:
+               case CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE:
+               case CALENDAR_EVENT_BUSY_STATUS_TENTATIVE:
+               (rec->busy_status) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //sensitivity
+    case CAL_PROPERTY_EVENT_SENSITIVITY:
+               switch (value)
+               {
+               case CALENDAR_SENSITIVITY_PUBLIC:
+               case CALENDAR_SENSITIVITY_PRIVATE:
+               case CALENDAR_SENSITIVITY_CONFIDENTIAL:
+               (rec->sensitivity) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //meeting_status
+    case CAL_PROPERTY_EVENT_MEETING_STATUS:
+               switch (value)
+               {
+               case CALENDAR_MEETING_STATUS_NOTMEETING:
+               case CALENDAR_MEETING_STATUS_MEETING:
+               case CALENDAR_MEETING_STATUS_RECEIVED:
+               case CALENDAR_MEETING_STATUS_CANCELED:
+               (rec->meeting_status) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //original_event_id
+    case CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID:
+        (rec->original_event_id) = value;
+        break;
+    //email_id
+    case CAL_PROPERTY_EVENT_EMAIL_ID:
+        (rec->email_id) = value;
+        break;
+    //is_deleted
+    case CAL_PROPERTY_EVENT_IS_DELETED:
+        (rec->is_deleted) = value;
+        break;
+    //freq
+    case CAL_PROPERTY_EVENT_FREQ:
+               switch (value)
+               {
+               case CALENDAR_RECURRENCE_NONE:
+               case CALENDAR_RECURRENCE_DAILY:
+               case CALENDAR_RECURRENCE_WEEKLY:
+               case CALENDAR_RECURRENCE_MONTHLY:
+               case CALENDAR_RECURRENCE_YEARLY:
+               (rec->freq) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //range_type
+    case CAL_PROPERTY_EVENT_RANGE_TYPE:
+               switch (value)
+               {
+               case CALENDAR_RANGE_UNTIL:
+               case CALENDAR_RANGE_COUNT:
+               case CALENDAR_RANGE_NONE:
+               (rec->range_type) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //count
+    case CAL_PROPERTY_EVENT_COUNT:
+        (rec->count) = value;
+        break;
+    //interval
+    case CAL_PROPERTY_EVENT_INTERVAL:
+        (rec->interval) = value;
+        break;
+    //wkst
+    case CAL_PROPERTY_EVENT_WKST:
+               switch (value)
+               {
+               case CALENDAR_SUNDAY:
+               case CALENDAR_MONDAY:
+               case CALENDAR_TUESDAY:
+               case CALENDAR_WEDNESDAY:
+               case CALENDAR_THURSDAY:
+               case CALENDAR_FRIDAY:
+               case CALENDAR_SATURDAY:
+               (rec->wkst) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //has_attendee
+    case CAL_PROPERTY_EVENT_HAS_ATTENDEE:
+        (rec->has_attendee) = value;
+        break;
+    //has_alarm
+    case CAL_PROPERTY_EVENT_HAS_ALARM:
+        (rec->has_alarm) = value;
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE:
+               switch (value)
+               {
+               case CALENDAR_SYSTEM_NONE:
+               case CALENDAR_SYSTEM_GREGORIAN:
+               case CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR:
+               (rec->system_type) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    case CAL_PROPERTY_EVENT_IS_ALLDAY:
+        (rec->start.type) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_set_double( calendar_record_h record, unsigned int property_id, double value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_LATITUDE:
+        (rec->latitude) = value;
+        break;
+    case CAL_PROPERTY_EVENT_LONGITUDE:
+        (rec->longitude) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_CREATED_TIME:
+        (rec->created_time) = value;
+        break;
+    case CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME:
+        (rec->last_mod) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_START:
+        rec->start = value;
+        break;
+    case CAL_PROPERTY_EVENT_END:
+        rec->end = value;
+        break;
+    case CAL_PROPERTY_EVENT_UNTIL:
+        (rec->until_type) = value.type;
+        if(value.type == CALENDAR_TIME_UTIME)
+        {
+            (rec->until_utime) = value.time.utime;
+            (rec->until_year) = 0;
+            (rec->until_month) = 0;
+            (rec->until_mday) = 0;
+        }
+        else
+        {
+            (rec->until_utime) = 0;
+            (rec->until_year) = value.time.date.year;
+            (rec->until_month) = value.time.date.month;
+            (rec->until_mday) = value.time.date.mday ;
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_add_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_CALENDAR_ALARM:
+        rec->alarm_list = g_list_append(rec->alarm_list,child_record);
+        rec->has_alarm = 1;
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE:
+        rec->attendee_list = g_list_append(rec->attendee_list,child_record);
+        rec->has_attendee = 1;
+        break;
+    case CAL_PROPERTY_EVENT_EXCEPTION:
+        rec->exception_list = g_list_append(rec->exception_list,child_record);
+        break;
+    case CAL_PROPERTY_EVENT_EXTENDED:
+        rec->extended_list = g_list_append(rec->extended_list,child_record);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_remove_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    //GList* node = NULL;
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_CALENDAR_ALARM:
+        rec->alarm_list = g_list_remove(rec->alarm_list,child_record);
+        if (g_list_length(rec->alarm_list) == 0)
+        {
+            rec->has_alarm = 0;
+        }
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE:
+        rec->attendee_list = g_list_remove(rec->attendee_list,child_record);
+        if (g_list_length(rec->attendee_list) == 0)
+        {
+            rec->has_attendee = 0;
+        }
+        break;
+    case CAL_PROPERTY_EVENT_EXCEPTION:
+        rec->exception_list = g_list_remove(rec->exception_list,child_record);
+        break;
+    case CAL_PROPERTY_EVENT_EXTENDED:
+        rec->extended_list = g_list_remove(rec->extended_list,child_record);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_child_record_count( calendar_record_h record, unsigned int property_id, unsigned int* count  )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    *count = 0;
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_CALENDAR_ALARM:
+        if (rec->alarm_list)
+        {
+            *count = g_list_length(rec->alarm_list);
+        }
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE:
+        if (rec->attendee_list)
+        {
+            *count = g_list_length(rec->attendee_list);
+        }
+        break;
+    case CAL_PROPERTY_EVENT_EXCEPTION:
+        if (rec->exception_list)
+        {
+            *count = g_list_length(rec->exception_list);
+        }
+        break;
+    case CAL_PROPERTY_EVENT_EXTENDED:
+        if (rec->extended_list)
+        {
+            *count = g_list_length(rec->extended_list);
+        }
+        break;
+    default:
+        *count = 0;
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_get_child_record_at_p( calendar_record_h record, unsigned int property_id, int index, calendar_record_h* child_record )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EVENT_CALENDAR_ALARM:
+        *child_record = g_list_nth_data(rec->alarm_list,index);
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE:
+        *child_record = g_list_nth_data(rec->attendee_list,index);
+        break;
+    case CAL_PROPERTY_EVENT_EXCEPTION:
+        *child_record = g_list_nth_data(rec->exception_list,index);
+        break;
+    case CAL_PROPERTY_EVENT_EXTENDED:
+        *child_record = g_list_nth_data(rec->extended_list,index);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_event_clone_child_record_list( calendar_record_h record, unsigned int property_id, calendar_list_h* out_list )
+{
+    cal_event_s *rec = (cal_event_s*)(record);
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_list_h list;
+    int count = 0;
+
+    ret = calendar_list_create(&list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_list_create fail");
+        return ret;
+    }
+
+       switch( property_id )
+       {
+       case CAL_PROPERTY_EVENT_CALENDAR_ALARM:
+    {
+        count = g_list_length(rec->alarm_list);
+        if (count <=0 )
+        {
+            calendar_list_destroy(list, true);
+            return CALENDAR_ERROR_NO_DATA;
+        }
+        GList *alarm_list = rec->alarm_list;
+        calendar_record_h alarm_child_record;
+        calendar_record_h alarm_record = NULL;
+        while (alarm_list)
+        {
+            alarm_child_record = (calendar_record_h)alarm_list->data;
+            if (alarm_child_record == NULL)
+            {
+                alarm_list = g_list_next(alarm_list);
+                continue;
+            }
+
+            if ( calendar_record_clone(alarm_child_record,&alarm_record) == CALENDAR_ERROR_NONE )
+            {
+                calendar_list_add(list,alarm_record);
+            }
+            alarm_record = NULL;
+
+            alarm_list = g_list_next(alarm_list);
+        }
+        *out_list = (calendar_list_h)list;
+    }
+    break;
+       case CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE:
+    {
+        count = g_list_length(rec->attendee_list);
+        if (count <=0 )
+        {
+            calendar_list_destroy(list, true);
+            return CALENDAR_ERROR_NO_DATA;
+        }
+        GList *attendee_list = rec->attendee_list;
+        calendar_record_h attendee_child_record;
+        calendar_record_h attendee_record = NULL;
+        while (attendee_list)
+        {
+            attendee_child_record = (calendar_record_h)attendee_list->data;
+            if (attendee_child_record == NULL)
+            {
+                attendee_list = g_list_next(attendee_list);
+                continue;
+            }
+
+            if ( calendar_record_clone(attendee_child_record,&attendee_record) == CALENDAR_ERROR_NONE )
+            {
+                calendar_list_add(list,attendee_record);
+            }
+            attendee_record = NULL;
+
+            attendee_list = g_list_next(attendee_list);
+        }
+        *out_list = (calendar_list_h)list;
+    }
+    break;
+    case CAL_PROPERTY_EVENT_EXCEPTION:
+    {
+        count = g_list_length(rec->exception_list);
+        if (count <=0 )
+        {
+            calendar_list_destroy(list, true);
+            return CALENDAR_ERROR_NO_DATA;
+        }
+        GList *exception_list = rec->exception_list;
+        calendar_record_h child_record;
+        calendar_record_h record = NULL;
+        while (exception_list)
+        {
+            child_record = (calendar_record_h)exception_list->data;
+            if (child_record == NULL)
+            {
+                exception_list = g_list_next(exception_list);
+                continue;
+            }
+
+            if ( calendar_record_clone(child_record,&record) == CALENDAR_ERROR_NONE )
+            {
+                calendar_list_add(list,record);
+            }
+            record = NULL;
+
+            exception_list = g_list_next(exception_list);
+        }
+        *out_list = (calendar_list_h)list;
+    }
+    break;
+    case CAL_PROPERTY_EVENT_EXTENDED:
+    {
+        count = g_list_length(rec->extended_list);
+        if (count <=0 )
+        {
+            calendar_list_destroy(list, true);
+            return CALENDAR_ERROR_NO_DATA;
+        }
+        GList *extended_list = rec->extended_list;
+        calendar_record_h child_record;
+        calendar_record_h record = NULL;
+        while (extended_list)
+        {
+            child_record = (calendar_record_h)extended_list->data;
+            if (child_record == NULL)
+            {
+                extended_list = g_list_next(extended_list);
+                continue;
+            }
+
+            if ( calendar_record_clone(child_record,&record) == CALENDAR_ERROR_NONE )
+            {
+                calendar_list_add(list,record);
+            }
+            record = NULL;
+
+            extended_list = g_list_next(extended_list);
+        }
+        *out_list = (calendar_list_h)list;
+    }
+    break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
diff --git a/common/cal_record_extended.c b/common/cal_record_extended.c
new file mode 100644 (file)
index 0000000..0a1fa0d
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_extended_create( calendar_record_h* out_record );
+static int __cal_record_extended_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_extended_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_extended_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_extended_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_extended_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_extended_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_extended_set_int( calendar_record_h record, unsigned int property_id, int value );
+
+cal_record_plugin_cb_s _cal_record_extended_plugin_cb = {
+        .create = __cal_record_extended_create,
+        .destroy = __cal_record_extended_destroy,
+        .clone = __cal_record_extended_clone,
+        .get_str = __cal_record_extended_get_str,
+        .get_str_p = __cal_record_extended_get_str_p,
+        .get_int = __cal_record_extended_get_int,
+        .get_double = NULL,
+        .get_lli = NULL,
+        .get_caltime = NULL,
+        .set_str = __cal_record_extended_set_str,
+        .set_int = __cal_record_extended_set_int,
+        .set_double = NULL,
+        .set_lli = NULL,
+        .set_caltime = 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 void __cal_record_extended_struct_init(cal_extended_s *record)
+{
+    memset(record,0,sizeof(cal_extended_s));
+}
+
+static int __cal_record_extended_create( calendar_record_h* out_record )
+{
+    cal_extended_s *temp = NULL;
+    int ret= CALENDAR_ERROR_NONE, type = 0;
+
+    type = CAL_RECORD_TYPE_EXTENDED;
+
+    temp = (cal_extended_s*)calloc(1,sizeof(cal_extended_s));
+    retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_extended_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    __cal_record_extended_struct_init(temp);
+
+    *out_record = (calendar_record_h)temp;
+
+    return ret;
+}
+
+static void __cal_record_extended_struct_free(cal_extended_s *record)
+{
+    CAL_FREE(record->key);
+    CAL_FREE(record->value);
+    CAL_FREE(record);
+
+}
+
+static int __cal_record_extended_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_extended_s *temp = (cal_extended_s*)(record);
+
+    __cal_record_extended_struct_free(temp);
+
+    return ret;
+}
+
+static int __cal_record_extended_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+    cal_extended_s *out_data = NULL;
+    cal_extended_s *src_data = NULL;
+
+    src_data = (cal_extended_s*)(record);
+
+    out_data = calloc(1, sizeof(cal_extended_s));
+    retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_extended_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+    out_data->id = src_data->id;
+    out_data->record_id = src_data->record_id;
+    out_data->record_type = src_data->record_type;
+    out_data->key = SAFE_STRDUP(src_data->key);
+    out_data->value = SAFE_STRDUP(src_data->value);
+
+    *out_record = (calendar_record_h)out_data;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_extended_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_extended_s *rec = (cal_extended_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EXTENDED_KEY:
+        *out_str = SAFE_STRDUP(rec->key);
+        break;
+    case CAL_PROPERTY_EXTENDED_VALUE:
+        *out_str = SAFE_STRDUP(rec->value);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_extended_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_extended_s *rec = (cal_extended_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EXTENDED_KEY:
+        *out_str = (rec->key);
+        break;
+    case CAL_PROPERTY_EXTENDED_VALUE:
+        *out_str = (rec->value);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_extended_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+    cal_extended_s *rec = (cal_extended_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EXTENDED_ID:
+        *out_value = (rec->id);
+        break;
+    case CAL_PROPERTY_EXTENDED_RECORD_ID:
+        *out_value = (rec->record_id);
+        break;
+    case CAL_PROPERTY_EXTENDED_RECORD_TYPE:
+        *out_value = (rec->record_type);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_extended_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    cal_extended_s *rec = (cal_extended_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EXTENDED_KEY:
+        CAL_FREE(rec->key);
+        rec->key = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_EXTENDED_VALUE:
+        CAL_FREE(rec->value);
+        rec->value = SAFE_STRDUP(value);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_extended_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    cal_extended_s *rec = (cal_extended_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_EXTENDED_ID:
+        (rec->id) = value;
+        break;
+    case CAL_PROPERTY_EXTENDED_RECORD_ID:
+        (rec->record_id) = value;
+        break;
+    case CAL_PROPERTY_EXTENDED_RECORD_TYPE:
+        (rec->record_type) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_instance_allday.c b/common/cal_record_instance_allday.c
new file mode 100644 (file)
index 0000000..a96cdf1
--- /dev/null
@@ -0,0 +1,425 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>        //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_instance_allday_create( calendar_record_h* out_record );
+static int __cal_record_instance_allday_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_instance_allday_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_instance_allday_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_instance_allday_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_instance_allday_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_instance_allday_get_double( calendar_record_h record, unsigned int property_id, double* out_value );
+static int __cal_record_instance_allday_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value );
+static int __cal_record_instance_allday_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value );
+static int __cal_record_instance_allday_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_instance_allday_set_int( calendar_record_h record, unsigned int property_id, int value );
+static int __cal_record_instance_allday_set_double( calendar_record_h record, unsigned int property_id, double value );
+static int __cal_record_instance_allday_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+static int __cal_record_instance_allday_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value );
+
+cal_record_plugin_cb_s _cal_record_instance_allday_plugin_cb = {
+    .create = __cal_record_instance_allday_create,
+    .destroy = __cal_record_instance_allday_destroy,
+    .clone = __cal_record_instance_allday_clone,
+    .get_str = __cal_record_instance_allday_get_str,
+    .get_str_p = __cal_record_instance_allday_get_str_p,
+    .get_int = __cal_record_instance_allday_get_int,
+    .get_double = __cal_record_instance_allday_get_double,
+    .get_lli = __cal_record_instance_allday_get_lli,
+    .get_caltime = __cal_record_instance_allday_get_caltime,
+    .set_str = __cal_record_instance_allday_set_str,
+    .set_int = __cal_record_instance_allday_set_int,
+    .set_double = __cal_record_instance_allday_set_double,
+    .set_lli = __cal_record_instance_allday_set_lli,
+    .set_caltime = __cal_record_instance_allday_set_caltime,
+    .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 void __cal_record_instance_allday_struct_init(cal_instance_allday_s* record)
+{
+    memset(record,0,sizeof(cal_instance_allday_s));
+
+    record->event_status = CALENDAR_EVENT_STATUS_NONE;
+    record->calendar_id = DEFAULT_EVENT_CALENDAR_BOOK_ID;
+    record->event_id = CAL_INVALID_ID;
+
+    record->busy_status = 2;
+    record->summary = NULL;
+    record->description = NULL;
+    record->location= NULL;
+
+    record->latitude = 1000; // set default 1000 out of range(-180 ~ 180)
+    record->longitude = 1000; // set default 1000 out of range(-180 ~ 180)
+
+    return;
+}
+
+static int __cal_record_instance_allday_create( calendar_record_h* out_record )
+{
+    cal_instance_allday_s *temp = NULL;
+    int ret= CALENDAR_ERROR_NONE, type = 0;
+
+    type = CAL_RECORD_TYPE_INSTANCE_ALLDAY;
+
+    temp = (cal_instance_allday_s*)calloc(1,sizeof(cal_instance_allday_s));
+    retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_instance_allday_s:sch) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    __cal_record_instance_allday_struct_init(temp);
+
+    *out_record = (calendar_record_h)temp;
+
+    return ret;
+}
+
+static void __cal_record_instance_allday_struct_free(cal_instance_allday_s *record)
+{
+    CAL_FREE(record->summary);
+    CAL_FREE(record->description);
+    CAL_FREE(record->location);
+
+    CAL_FREE(record);
+}
+
+static int __cal_record_instance_allday_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_instance_allday_s *temp = (cal_instance_allday_s*)(record);
+
+    __cal_record_instance_allday_struct_free(temp);
+
+    return ret;
+}
+
+static int __cal_record_instance_allday_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+    cal_instance_allday_s *out_data = NULL;
+    cal_instance_allday_s *src_data = NULL;
+
+    src_data = (cal_instance_allday_s*)(record);
+
+    out_data = calloc(1, sizeof(cal_instance_allday_s));
+    retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_instance_allday_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+    out_data->event_id = src_data->event_id;
+    out_data->calendar_id = src_data->calendar_id;
+    out_data->dtstart_type = src_data->dtstart_type;
+    out_data->dtstart_year = src_data->dtstart_year;
+    out_data->dtstart_month = src_data->dtstart_month;
+    out_data->dtstart_mday = src_data->dtstart_mday;
+    out_data->dtend_type = src_data->dtend_type;
+    out_data->dtend_year = src_data->dtend_year;
+    out_data->dtend_month = src_data->dtend_month;
+    out_data->dtend_mday = src_data->dtend_mday;
+    out_data->summary = SAFE_STRDUP(src_data->summary);
+    out_data->description = SAFE_STRDUP(src_data->description);
+    out_data->location = SAFE_STRDUP(src_data->location);
+    out_data->busy_status = src_data->busy_status;
+    out_data->event_status = src_data->event_status;
+    out_data->priority = src_data->priority;
+    out_data->sensitivity = src_data->sensitivity;
+    out_data->has_rrule = src_data->has_rrule;
+    out_data->latitude = src_data->latitude;
+    out_data->longitude = src_data->longitude;
+    out_data->has_alarm = src_data->has_alarm;
+    out_data->original_event_id = src_data->original_event_id;
+    out_data->last_mod = src_data->last_mod;
+
+    *out_record = (calendar_record_h)out_data;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY:
+        *out_str = SAFE_STRDUP(rec->summary);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION:
+        *out_str = SAFE_STRDUP(rec->description);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION:
+        *out_str = SAFE_STRDUP(rec->location);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY:
+        *out_str = (rec->summary);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION:
+        *out_str = (rec->description);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION:
+        *out_str = (rec->location);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID:
+        *out_value = (rec->event_id);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID:
+        *out_value = (rec->calendar_id);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS:
+        *out_value = (rec->busy_status);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS:
+        *out_value = (rec->event_status);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY:
+        *out_value = (rec->priority);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY:
+        *out_value = (rec->sensitivity);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE:
+        *out_value = (rec->has_rrule);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM:
+        *out_value = (rec->has_alarm);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID:
+        *out_value = (rec->original_event_id);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_get_double( calendar_record_h record, unsigned int property_id, double* out_value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE:
+        *out_value = (rec->latitude);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE:
+        *out_value = (rec->longitude);
+        break;
+
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME:
+        *out_value = (rec->last_mod);
+        break;
+    default:
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_START:
+        CAL_CALTIME_SET_DATE(*out_value,(rec->dtstart_year),(rec->dtstart_month),(rec->dtstart_mday));
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_END:
+        CAL_CALTIME_SET_DATE(*out_value,(rec->dtend_year),(rec->dtend_month),(rec->dtend_mday));
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY:
+        CAL_FREE(rec->summary);
+        rec->summary = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION:
+        CAL_FREE(rec->description);
+        rec->description = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION:
+        CAL_FREE(rec->location);
+        rec->location = SAFE_STRDUP(value);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID:
+        (rec->event_id) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID:
+        (rec->calendar_id) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS:
+        (rec->busy_status) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS:
+        (rec->event_status) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY:
+        (rec->priority) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY:
+        (rec->sensitivity) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE:
+        (rec->has_rrule) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM:
+        (rec->has_alarm) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID:
+        (rec->original_event_id) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_set_double( calendar_record_h record, unsigned int property_id, double value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE:
+        (rec->latitude) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE:
+        (rec->longitude) = value;
+        break;
+
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME:
+        (rec->last_mod) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_allday_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value )
+{
+    cal_instance_allday_s *rec = (cal_instance_allday_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_START:
+        (rec->dtstart_type) = CALENDAR_TIME_LOCALTIME;//value.type;
+        (rec->dtstart_year) = value.time.date.year;
+        (rec->dtstart_month) = value.time.date.month;
+        (rec->dtstart_mday) = value.time.date.mday ;
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_END:
+        (rec->dtend_type) = CALENDAR_TIME_LOCALTIME;//value.type;
+        (rec->dtend_year) = value.time.date.year;
+        (rec->dtend_month) = value.time.date.month;
+        (rec->dtend_mday) = value.time.date.mday ;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_instance_normal.c b/common/cal_record_instance_normal.c
new file mode 100644 (file)
index 0000000..ac2d477
--- /dev/null
@@ -0,0 +1,415 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>        //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_instance_normal_create( calendar_record_h* out_record );
+static int __cal_record_instance_normal_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_instance_normal_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_instance_normal_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_instance_normal_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_instance_normal_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_instance_normal_get_double( calendar_record_h record, unsigned int property_id, double* out_value );
+static int __cal_record_instance_normal_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value );
+static int __cal_record_instance_normal_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value );
+static int __cal_record_instance_normal_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_instance_normal_set_int( calendar_record_h record, unsigned int property_id, int value );
+static int __cal_record_instance_normal_set_double( calendar_record_h record, unsigned int property_id, double value );
+static int __cal_record_instance_normal_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+static int __cal_record_instance_normal_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value );
+
+cal_record_plugin_cb_s _cal_record_instance_normal_plugin_cb = {
+    .create = __cal_record_instance_normal_create,
+    .destroy = __cal_record_instance_normal_destroy,
+    .clone = __cal_record_instance_normal_clone,
+    .get_str = __cal_record_instance_normal_get_str,
+    .get_str_p = __cal_record_instance_normal_get_str_p,
+    .get_int = __cal_record_instance_normal_get_int,
+    .get_double = __cal_record_instance_normal_get_double,
+    .get_lli = __cal_record_instance_normal_get_lli,
+    .get_caltime = __cal_record_instance_normal_get_caltime,
+    .set_str = __cal_record_instance_normal_set_str,
+    .set_int = __cal_record_instance_normal_set_int,
+    .set_double = __cal_record_instance_normal_set_double,
+    .set_lli = __cal_record_instance_normal_set_lli,
+    .set_caltime = __cal_record_instance_normal_set_caltime,
+    .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 void __cal_record_instance_normal_struct_init(cal_instance_normal_s* record)
+{
+    memset(record,0,sizeof(cal_instance_normal_s));
+
+    record->event_status = CALENDAR_EVENT_STATUS_NONE;
+    record->calendar_id = DEFAULT_EVENT_CALENDAR_BOOK_ID;
+    record->event_id = CAL_INVALID_ID;
+
+    record->busy_status = 2;
+    record->summary = NULL;
+    record->description = NULL;
+    record->location= NULL;
+
+    record->latitude = 1000; // set default 1000 out of range(-180 ~ 180)
+    record->longitude = 1000; // set default 1000 out of range(-180 ~ 180)
+
+    return ;
+}
+
+static int __cal_record_instance_normal_create( calendar_record_h* out_record )
+{
+    cal_instance_normal_s *temp = NULL;
+    int ret= CALENDAR_ERROR_NONE, type = 0;
+
+    type = CAL_RECORD_TYPE_INSTANCE_NORMAL;
+
+    temp = (cal_instance_normal_s*)calloc(1,sizeof(cal_instance_normal_s));
+    retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_instance_normal_s:sch) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    __cal_record_instance_normal_struct_init(temp);
+
+    *out_record = (calendar_record_h)temp;
+
+    return ret;
+}
+
+static void __cal_record_instance_normal_struct_free(cal_instance_normal_s *record)
+{
+    CAL_FREE(record->summary);
+    CAL_FREE(record->description);
+    CAL_FREE(record->location);
+
+    CAL_FREE(record);
+}
+
+static int __cal_record_instance_normal_destroy( calendar_record_h record, bool delete_child )
+{
+    cal_instance_normal_s *temp = (cal_instance_normal_s*)(record);
+
+    __cal_record_instance_normal_struct_free(temp);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+    cal_instance_normal_s *out_data = NULL;
+    cal_instance_normal_s *src_data = NULL;
+
+    src_data = (cal_instance_normal_s*)(record);
+
+    out_data = calloc(1, sizeof(cal_instance_normal_s));
+    retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_instance_normal_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+    out_data->event_id = src_data->event_id;
+    out_data->calendar_id = src_data->calendar_id;
+    out_data->dtstart_type = src_data->dtstart_type;
+    out_data->dtstart_utime = src_data->dtstart_utime;
+    out_data->dtend_type = src_data->dtend_type;
+    out_data->dtend_utime = src_data->dtend_utime;
+    out_data->summary = SAFE_STRDUP(src_data->summary);
+    out_data->description = SAFE_STRDUP(src_data->description);
+    out_data->location = SAFE_STRDUP(src_data->location);
+    out_data->busy_status = src_data->busy_status;
+    out_data->event_status = src_data->event_status;
+    out_data->priority = src_data->priority;
+    out_data->sensitivity = src_data->sensitivity;
+    out_data->has_rrule = src_data->has_rrule;
+    out_data->latitude = src_data->latitude;
+    out_data->longitude = src_data->longitude;
+    out_data->has_alarm = src_data->has_alarm;
+    out_data->original_event_id = src_data->original_event_id;
+    out_data->last_mod = src_data->last_mod;
+
+    *out_record = (calendar_record_h)out_data;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY:
+        *out_str = SAFE_STRDUP(rec->summary);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION:
+        *out_str = SAFE_STRDUP(rec->description);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LOCATION:
+        *out_str = SAFE_STRDUP(rec->location);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY:
+        *out_str = (rec->summary);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION:
+        *out_str = (rec->description);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LOCATION:
+        *out_str = (rec->location);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID:
+        *out_value = (rec->event_id);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID:
+        *out_value = (rec->calendar_id);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS:
+        *out_value = (rec->busy_status);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS:
+        *out_value = (rec->event_status);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY:
+        *out_value = (rec->priority);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY:
+        *out_value = (rec->sensitivity);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE:
+        *out_value = (rec->has_rrule);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM:
+        *out_value = (rec->has_alarm);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID:
+        *out_value = (rec->original_event_id);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_get_double( calendar_record_h record, unsigned int property_id, double* out_value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE:
+        *out_value = (rec->latitude);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE:
+        *out_value = (rec->longitude);
+        break;
+
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME:
+        *out_value = (rec->last_mod);
+        break;
+    default:
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_START:
+        CAL_CALTIME_SET_UTIME(*out_value,(rec->dtstart_utime));
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_END:
+        CAL_CALTIME_SET_UTIME(*out_value,(rec->dtend_utime));
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY:
+        CAL_FREE(rec->summary);
+        rec->summary = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION:
+        CAL_FREE(rec->description);
+        rec->description = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LOCATION:
+        CAL_FREE(rec->location);
+        rec->location = SAFE_STRDUP(value);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID:
+        (rec->event_id) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID:
+        (rec->calendar_id) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS:
+        (rec->busy_status) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS:
+        (rec->event_status) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY:
+        (rec->priority) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY:
+        (rec->sensitivity) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE:
+        (rec->has_rrule) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM:
+        (rec->has_alarm) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID:
+        (rec->original_event_id) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_set_double( calendar_record_h record, unsigned int property_id, double value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE:
+        (rec->latitude) = value;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE:
+        (rec->longitude) = value;
+        break;
+
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME:
+        (rec->last_mod) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_instance_normal_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value )
+{
+    cal_instance_normal_s *rec = (cal_instance_normal_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_START:
+        (rec->dtstart_type) = CALENDAR_TIME_UTIME;//value.type;
+        (rec->dtstart_utime) = value.time.utime;
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_END:
+        (rec->dtend_type) = CALENDAR_TIME_UTIME;//value.type;
+        (rec->dtend_utime) = value.time.utime;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_search.c b/common/cal_record_search.c
new file mode 100644 (file)
index 0000000..b35a255
--- /dev/null
@@ -0,0 +1,480 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>        //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_search_create( calendar_record_h* out_record );
+static int __cal_record_search_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_search_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_search_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_search_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_search_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_search_get_double( calendar_record_h record, unsigned int property_id, double* out_value );
+static int __cal_record_search_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value );
+static int __cal_record_search_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value );
+static int __cal_record_search_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_search_set_int( calendar_record_h record, unsigned int property_id, int value );
+static int __cal_record_search_set_double( calendar_record_h record, unsigned int property_id, double value );
+static int __cal_record_search_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+static int __cal_record_search_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value );
+
+cal_record_plugin_cb_s _cal_record_search_plugin_cb = {
+    .create = __cal_record_search_create,
+    .destroy = __cal_record_search_destroy,
+    .clone = __cal_record_search_clone,
+    .get_str = __cal_record_search_get_str,
+    .get_str_p = __cal_record_search_get_str_p,
+    .get_int = __cal_record_search_get_int,
+    .get_double = __cal_record_search_get_double,
+    .get_lli = __cal_record_search_get_lli,
+    .get_caltime = __cal_record_search_get_caltime,
+    .set_str = __cal_record_search_set_str,
+    .set_int = __cal_record_search_set_int,
+    .set_double = __cal_record_search_set_double,
+    .set_lli = __cal_record_search_set_lli,
+    .set_caltime = __cal_record_search_set_caltime,
+    .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 __cal_record_search_create( calendar_record_h* out_record )
+{
+    cal_search_s *temp = NULL;
+    int ret= CALENDAR_ERROR_NONE;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    type = CAL_RECORD_TYPE_SEARCH;
+
+    temp = (cal_search_s*)calloc(1, sizeof(cal_search_s));
+    retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_search_s:sch) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    *out_record = (calendar_record_h)temp;
+
+    return ret;
+}
+
+static int __cal_record_search_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    GSList *cursor;
+
+    cal_search_s *temp = (cal_search_s*)(record);
+
+    for(cursor = temp->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *data = cursor->data;
+        if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_STR) == true)
+        {
+            CAL_FREE(data->value.s);
+        }
+        CAL_FREE(data);
+    }
+
+    g_slist_free(temp->values);
+    CAL_FREE(temp);
+
+    return ret;
+}
+
+static int __cal_record_search_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    cal_search_s *out_data = NULL;
+    cal_search_s *src_data = NULL;
+    GSList *cursor;
+
+    src_data = (cal_search_s*)(record);
+
+    out_data = calloc(1, sizeof(cal_search_s));
+    retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_search_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+    for(cursor = src_data->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *src = cursor->data;
+        cal_search_value_s *dest = calloc(1, sizeof(cal_search_value_s));
+        if (dest == NULL)
+        {
+            CAL_FREE(out_data);
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+            return ret;
+        }
+        dest->property_id = src->property_id;
+        if (CAL_PROPERTY_CHECK_DATA_TYPE(src->property_id, CAL_PROPERTY_DATA_TYPE_STR) == true)
+        {
+            dest->value.s = SAFE_STRDUP(src->value.s);
+        }
+        else if (CAL_PROPERTY_CHECK_DATA_TYPE(src->property_id, CAL_PROPERTY_DATA_TYPE_INT) == true)
+        {
+            dest->value.i = src->value.i;
+        }
+        else if (CAL_PROPERTY_CHECK_DATA_TYPE(src->property_id, CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+        {
+            dest->value.d = src->value.d;
+        }
+        else if (CAL_PROPERTY_CHECK_DATA_TYPE(src->property_id, CAL_PROPERTY_DATA_TYPE_LLI) == true)
+        {
+            dest->value.lli = src->value.lli;
+        }
+        else if (CAL_PROPERTY_CHECK_DATA_TYPE(src->property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+        {
+            dest->value.caltime = src->value.caltime;
+        }
+        else
+        {
+            ASSERT_NOT_REACHED("invalid parameter (property:%d)",src->property_id);
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+
+        out_data->values = g_slist_append(out_data->values, dest);
+    }
+
+    *out_record = (calendar_record_h)out_data;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_STR) == true)
+            {
+                *out_str = SAFE_STRDUP(data->value.s);
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_STR) == true)
+            {
+                *out_str = (data->value.s);
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_INT) == true)
+            {
+                *out_value = (data->value.i);
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_get_double( calendar_record_h record, unsigned int property_id, double* out_value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+            {
+                *out_value = (data->value.d);
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_LLI) == true)
+            {
+                *out_value = (data->value.lli);
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        cal_search_value_s *data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+            {
+                *out_value = (data->value.caltime);
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+    cal_search_value_s *data = NULL;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_STR) == true)
+            {
+                CAL_FREE(data->value.s);
+                (data->value.s) = SAFE_STRDUP(value);
+                return CALENDAR_ERROR_NONE;
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    data = calloc(1, sizeof(cal_search_value_s));
+    retvm_if(NULL == data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_search_s) Failed");
+    data->property_id = property_id;
+    data->value.s = SAFE_STRDUP(value);
+    rec->values = g_slist_append(rec->values, data);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+    cal_search_value_s *data = NULL;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_INT) == true)
+            {
+                (data->value.i) = value;
+                return CALENDAR_ERROR_NONE;
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    data = calloc(1, sizeof(cal_search_value_s));
+    retvm_if(NULL == data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_search_s) Failed");
+    data->property_id = property_id;
+    (data->value.i) = value;
+    rec->values = g_slist_append(rec->values, data);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_set_double( calendar_record_h record, unsigned int property_id, double value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+    cal_search_value_s *data = NULL;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+            {
+                (data->value.d) = value;
+                return CALENDAR_ERROR_NONE;
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    data = calloc(1, sizeof(cal_search_value_s));
+    retvm_if(NULL == data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_search_s) Failed");
+    data->property_id = property_id;
+    (data->value.d) = value;
+    rec->values = g_slist_append(rec->values, data);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+    cal_search_value_s *data = NULL;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_LLI) == true)
+            {
+                (data->value.lli) = value;
+                return CALENDAR_ERROR_NONE;
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    data = calloc(1, sizeof(cal_search_value_s));
+    retvm_if(NULL == data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_search_s) Failed");
+    data->property_id = property_id;
+    (data->value.lli) = value;
+    rec->values = g_slist_append(rec->values, data);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_search_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value )
+{
+    cal_search_s *rec = (cal_search_s*)(record);
+    GSList *cursor;
+    cal_search_value_s *data = NULL;
+
+    for(cursor = rec->values;cursor;cursor=cursor->next)
+    {
+        data = cursor->data;
+        if (data->property_id == property_id)
+        {
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(data->property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+            {
+                (data->value.caltime) = value;
+                return CALENDAR_ERROR_NONE;
+            }
+            else
+            {
+                ASSERT_NOT_REACHED("invalid parameter (property:%d)",data->property_id);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+        }
+    }
+
+    data = calloc(1, sizeof(cal_search_value_s));
+    retvm_if(NULL == data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_search_s) Failed");
+    data->property_id = property_id;
+    (data->value.caltime) = value;
+    rec->values = g_slist_append(rec->values, data);
+
+    return CALENDAR_ERROR_NONE;
+}
+
diff --git a/common/cal_record_timezone.c b/common/cal_record_timezone.c
new file mode 100644 (file)
index 0000000..27aef17
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_timezone_create( calendar_record_h* out_record );
+static int __cal_record_timezone_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_timezone_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_timezone_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_timezone_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_timezone_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_timezone_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_timezone_set_int( calendar_record_h record, unsigned int property_id, int value );
+
+cal_record_plugin_cb_s _cal_record_timezone_plugin_cb = {
+               .create = __cal_record_timezone_create,
+               .destroy = __cal_record_timezone_destroy,
+               .clone = __cal_record_timezone_clone,
+               .get_str = __cal_record_timezone_get_str,
+               .get_str_p = __cal_record_timezone_get_str_p,
+               .get_int = __cal_record_timezone_get_int,
+               .get_double = NULL,
+               .get_lli = NULL,
+               .get_caltime = NULL,
+               .set_str = __cal_record_timezone_set_str,
+               .set_int = __cal_record_timezone_set_int,
+               .set_double = NULL,
+               .set_lli = NULL,
+               .set_caltime = 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 void __cal_record_timezone_struct_init(cal_timezone_s *record)
+{
+       memset(record,0,sizeof(cal_timezone_s));
+    record->calendar_id = DEFAULT_EVENT_CALENDAR_BOOK_ID;
+}
+
+static int __cal_record_timezone_create( calendar_record_h* out_record )
+{
+       cal_timezone_s *temp = NULL;
+       int ret= CALENDAR_ERROR_NONE, type = 0;
+
+       type = CAL_RECORD_TYPE_TIMEZONE;
+
+       temp = (cal_timezone_s*)calloc(1,sizeof(cal_timezone_s));
+       retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_timezone_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+       __cal_record_timezone_struct_init(temp);
+
+    *out_record = (calendar_record_h)temp;
+
+       return ret;
+}
+
+static void __cal_record_timezone_struct_free(cal_timezone_s *record)
+{
+       CAL_FREE(record->standard_name);
+       CAL_FREE(record->day_light_name);
+       CAL_FREE(record);
+
+}
+
+static int __cal_record_timezone_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+       cal_timezone_s *temp = (cal_timezone_s*)(record);
+
+    __cal_record_timezone_struct_free(temp);
+
+       return ret;
+}
+
+static int __cal_record_timezone_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+       cal_timezone_s *out_data = NULL;
+       cal_timezone_s *src_data = NULL;
+
+       src_data = (cal_timezone_s*)(record);
+
+       out_data = calloc(1, sizeof(cal_timezone_s));
+       retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_timezone_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+       CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+       out_data->index = src_data->index;
+       out_data->tz_offset_from_gmt = src_data->tz_offset_from_gmt;
+       out_data->standard_name = SAFE_STRDUP(src_data->standard_name);
+       out_data->std_start_month = src_data->std_start_month;
+       out_data->std_start_position_of_week = src_data->std_start_position_of_week;
+       out_data->std_start_day = src_data->std_start_day;
+       out_data->std_start_hour = src_data->std_start_hour;
+       out_data->standard_bias = src_data->standard_bias;
+       out_data->day_light_name = SAFE_STRDUP(src_data->day_light_name);
+       out_data->day_light_start_month = src_data->day_light_start_month;
+       out_data->day_light_start_position_of_week = src_data->day_light_start_position_of_week;
+       out_data->day_light_start_day = src_data->day_light_start_day;
+       out_data->day_light_start_hour = src_data->day_light_start_hour;
+       out_data->day_light_bias = src_data->day_light_bias;
+       out_data->calendar_id = src_data->calendar_id;
+
+    *out_record = (calendar_record_h)out_data;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_timezone_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_timezone_s *rec = (cal_timezone_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_TIMEZONE_STANDARD_NAME:
+               *out_str = SAFE_STRDUP(rec->standard_name);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_NAME:
+               *out_str = SAFE_STRDUP(rec->day_light_name);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_timezone_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+       cal_timezone_s *rec = (cal_timezone_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_TIMEZONE_STANDARD_NAME:
+               *out_str = (rec->standard_name);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_NAME:
+               *out_str = (rec->day_light_name);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_timezone_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+       cal_timezone_s *rec = (cal_timezone_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_TIMEZONE_ID:
+               *out_value = (rec->index);
+               break;
+       case CAL_PROPERTY_TIMEZONE_TZ_OFFSET_FROM_GMT:
+               *out_value = (rec->tz_offset_from_gmt);
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_MONTH:
+               *out_value = (rec->std_start_month);
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_POSITION_OF_WEEK:
+               *out_value = (rec->std_start_position_of_week);
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_DAY:
+               *out_value = (rec->std_start_day);
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_HOUR:
+               *out_value = (rec->std_start_hour);
+               break;
+       case CAL_PROPERTY_TIMEZONE_STANDARD_BIAS:
+               *out_value = (rec->standard_bias);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_MONTH:
+               *out_value = (rec->day_light_start_month);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_POSITION_OF_WEEK:
+               *out_value = (rec->day_light_start_position_of_week);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_DAY:
+               *out_value = (rec->day_light_start_day);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_HOUR:
+               *out_value = (rec->day_light_start_hour);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_BIAS:
+               *out_value = (rec->day_light_bias);
+               break;
+       case CAL_PROPERTY_TIMEZONE_CALENDAR_ID:
+               *out_value = (rec->calendar_id);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_timezone_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+       cal_timezone_s *rec = (cal_timezone_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_TIMEZONE_STANDARD_NAME:
+               CAL_FREE(rec->standard_name);
+               rec->standard_name = SAFE_STRDUP(value);
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_NAME:
+               CAL_FREE(rec->day_light_name);
+               rec->day_light_name = SAFE_STRDUP(value);
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_timezone_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+       cal_timezone_s *rec = (cal_timezone_s*)(record);
+       switch( property_id )
+       {
+       case CAL_PROPERTY_TIMEZONE_ID:
+               (rec->index) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_TZ_OFFSET_FROM_GMT:
+               (rec->tz_offset_from_gmt) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_MONTH:
+               (rec->std_start_month) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_POSITION_OF_WEEK:
+               (rec->std_start_position_of_week) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_DAY:
+               (rec->std_start_day) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_STD_START_HOUR:
+               (rec->std_start_hour) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_STANDARD_BIAS:
+               (rec->standard_bias) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_MONTH:
+               (rec->day_light_start_month) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_POSITION_OF_WEEK:
+               (rec->day_light_start_position_of_week) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_DAY:
+               (rec->day_light_start_day) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_HOUR:
+               (rec->day_light_start_hour) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_BIAS:
+               (rec->day_light_bias) = value;
+               break;
+       case CAL_PROPERTY_TIMEZONE_CALENDAR_ID:
+               (rec->calendar_id) = value;
+               break;
+       default:
+           ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_todo.c b/common/cal_record_todo.c
new file mode 100644 (file)
index 0000000..e228965
--- /dev/null
@@ -0,0 +1,1205 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>           //bool
+#include <string.h>
+
+#include "calendar_list.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+#include "cal_record.h"
+
+static int __cal_record_todo_create( calendar_record_h* out_record );
+static int __cal_record_todo_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_todo_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_todo_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_todo_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+static int __cal_record_todo_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_todo_get_double( calendar_record_h record, unsigned int property_id, double* out_value );
+static int __cal_record_todo_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value );
+static int __cal_record_todo_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value );
+static int __cal_record_todo_set_str( calendar_record_h record, unsigned int property_id, const char* value );
+static int __cal_record_todo_set_int( calendar_record_h record, unsigned int property_id, int value );
+static int __cal_record_todo_set_double( calendar_record_h record, unsigned int property_id, double value );
+static int __cal_record_todo_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+static int __cal_record_todo_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value );
+static int __cal_record_todo_add_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record );
+static int __cal_record_todo_remove_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record );
+static int __cal_record_todo_get_child_record_count( calendar_record_h record, unsigned int property_id, unsigned int* count  );
+static int __cal_record_todo_get_child_record_at_p( calendar_record_h record, unsigned int property_id, int index, calendar_record_h* child_record );
+static int __cal_record_todo_clone_child_record_list( calendar_record_h record, unsigned int property_id, calendar_list_h* out_list );
+
+cal_record_plugin_cb_s _cal_record_todo_plugin_cb = {
+    .create = __cal_record_todo_create,
+    .destroy = __cal_record_todo_destroy,
+    .clone = __cal_record_todo_clone,
+    .get_str = __cal_record_todo_get_str,
+    .get_str_p = __cal_record_todo_get_str_p,
+    .get_int = __cal_record_todo_get_int,
+    .get_double = __cal_record_todo_get_double,
+    .get_lli = __cal_record_todo_get_lli,
+    .get_caltime = __cal_record_todo_get_caltime,
+    .set_str = __cal_record_todo_set_str,
+    .set_int = __cal_record_todo_set_int,
+    .set_double = __cal_record_todo_set_double,
+    .set_lli = __cal_record_todo_set_lli,
+    .set_caltime = __cal_record_todo_set_caltime,
+    .add_child_record = __cal_record_todo_add_child_record,
+    .remove_child_record = __cal_record_todo_remove_child_record,
+    .get_child_record_count = __cal_record_todo_get_child_record_count,
+    .get_child_record_at_p = __cal_record_todo_get_child_record_at_p,
+    .clone_child_record_list = __cal_record_todo_clone_child_record_list
+};
+
+static void __cal_record_todo_struct_init(cal_todo_s *record)
+{
+    memset(record,0,sizeof(cal_todo_s));
+
+    record->todo_status = CALENDAR_TODO_STATUS_NONE;
+    record->calendar_id = DEFAULT_TODO_CALENDAR_BOOK_ID;
+
+    record->index = CAL_INVALID_ID;
+    record->summary = NULL;
+    record->description = NULL;
+    record->location= NULL;
+    record->categories = NULL;
+    record->uid= NULL;
+    record->is_deleted = 0;
+    record->latitude = 1000; // set default 1000 out of range(-180 ~ 180)
+    record->longitude = 1000; // set default 1000 out of range(-180 ~ 180)
+    record->freq = CALENDAR_RECURRENCE_NONE;
+    record->until_utime = CALENDAR_RECORD_NO_UNTIL;
+    record->start.time.utime = CALENDAR_TODO_NO_START_DATE;
+    record->due.time.utime = CALENDAR_TODO_NO_DUE_DATE;
+
+    return ;
+}
+
+static int __cal_record_todo_create( calendar_record_h* out_record )
+{
+    cal_todo_s *temp = NULL;
+    int ret= CALENDAR_ERROR_NONE, type = 0;
+
+    type = CAL_RECORD_TYPE_TODO;
+
+    temp = (cal_todo_s*)calloc(1,sizeof(cal_todo_s));
+    retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_todo_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    __cal_record_todo_struct_init(temp);
+
+    *out_record = (calendar_record_h)temp;
+
+    return ret;
+}
+
+static void __cal_record_todo_struct_free(cal_todo_s *record, bool delete_child)
+{
+    CAL_FREE(record->summary);
+    CAL_FREE(record->description);
+    CAL_FREE(record->location);
+    CAL_FREE(record->categories);
+    CAL_FREE(record->uid);
+    CAL_FREE(record->start_tzid);
+    CAL_FREE(record->due_tzid);
+
+    CAL_FREE(record->bysecond);
+    CAL_FREE(record->byminute);
+    CAL_FREE(record->byhour);
+    CAL_FREE(record->byday);
+    CAL_FREE(record->bymonthday);
+    CAL_FREE(record->byyearday);
+    CAL_FREE(record->byweekno);
+    CAL_FREE(record->bymonth);
+    CAL_FREE(record->bysetpos);
+
+    CAL_FREE(record->sync_data1);
+    CAL_FREE(record->sync_data2);
+    CAL_FREE(record->sync_data3);
+    CAL_FREE(record->sync_data4);
+
+    CAL_FREE(record->organizer_name);
+    CAL_FREE(record->organizer_email);
+
+    if (delete_child == true)
+    {
+        if( record->alarm_list )
+        {
+            GList *alarm_list = record->alarm_list;
+            calendar_record_h alarm_child_record = NULL;
+            while (alarm_list)
+            {
+                alarm_child_record = (calendar_record_h)alarm_list->data;
+                if (alarm_child_record == NULL)
+                {
+                    alarm_list = g_list_next(alarm_list);
+                    continue;
+                }
+
+                calendar_record_destroy(alarm_child_record, true);
+
+                alarm_list = g_list_next(alarm_list);
+            }
+            g_list_free(record->alarm_list);
+            record->alarm_list = NULL;
+        }
+
+        if( record->attendee_list )
+        {
+            GList * attendee_list = g_list_first(record->attendee_list);
+            calendar_record_h attendee = NULL;
+
+            while (attendee_list)
+            {
+                attendee = (calendar_record_h)attendee_list->data;
+                if (attendee == NULL)
+                {
+                    attendee_list = g_list_next(attendee_list);
+                    continue;
+                }
+
+                calendar_record_destroy(attendee, true);
+
+                attendee_list = g_list_next(attendee_list);
+            }
+            g_list_free(record->attendee_list);
+            record->attendee_list = NULL;
+        }
+        if( record->extended_list )
+        {
+            GList * extended_list = g_list_first(record->extended_list);
+            calendar_record_h extended = NULL;
+
+            while (extended_list)
+            {
+                extended = (calendar_record_h)extended_list->data;
+                if (extended == NULL)
+                {
+                    extended_list = g_list_next(extended_list);
+                    continue;
+                }
+
+                calendar_record_destroy(extended, true);
+
+                extended_list = g_list_next(extended_list);
+            }
+            g_list_free(record->extended_list);
+            record->extended_list = NULL;
+        }
+    }
+
+    CAL_FREE(record);
+}
+
+static int __cal_record_todo_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_todo_s *temp = (cal_todo_s*)(record);
+
+    __cal_record_todo_struct_free(temp, delete_child);
+
+    return ret;
+}
+
+static int __cal_record_todo_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+    cal_todo_s *out_data = NULL;
+    cal_todo_s *src_data = NULL;
+
+    src_data = (cal_todo_s*)(record);
+
+    out_data = calloc(1, sizeof(cal_todo_s));
+    retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_todo_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+
+    CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+    out_data->index = src_data->index;
+    out_data->summary = SAFE_STRDUP(src_data->summary);
+    out_data->description = SAFE_STRDUP(src_data->description);
+    out_data->location = SAFE_STRDUP(src_data->location);
+    out_data->categories = SAFE_STRDUP(src_data->categories);
+
+    out_data->todo_status = src_data->todo_status;
+    out_data->priority = src_data->priority;
+    out_data->sensitivity = src_data->sensitivity;
+
+    out_data->uid = SAFE_STRDUP(src_data->uid);
+
+    out_data->calendar_id = src_data->calendar_id;
+    out_data->latitude = src_data->latitude;
+    out_data->longitude = src_data->longitude;
+
+    out_data->created_time = src_data->created_time;
+    out_data->completed_time = src_data->completed_time;
+    out_data->progress = src_data->progress;
+    out_data->is_deleted = src_data->is_deleted;
+    out_data->last_mod = src_data->last_mod;
+
+    out_data->freq = src_data->freq;
+    out_data->range_type = src_data->range_type;
+    out_data->until_type = src_data->until_type;
+    out_data->until_utime = src_data->until_utime;
+    out_data->until_year = src_data->until_year;
+    out_data->until_month = src_data->until_month;
+    out_data->until_mday = src_data->until_mday;
+    out_data->count = src_data->count;
+    out_data->interval = src_data->interval;
+    out_data->bysecond = SAFE_STRDUP(src_data->bysecond);
+    out_data->byminute = SAFE_STRDUP(src_data->byminute);
+    out_data->byhour = SAFE_STRDUP(src_data->byhour);
+    out_data->byday = SAFE_STRDUP(src_data->byday);
+    out_data->bymonthday = SAFE_STRDUP(src_data->bymonthday);
+    out_data->byyearday = SAFE_STRDUP(src_data->byyearday);
+    out_data->byweekno = SAFE_STRDUP(src_data->byweekno);
+    out_data->bymonth = SAFE_STRDUP(src_data->bymonth);
+    out_data->bysetpos = SAFE_STRDUP(src_data->bysetpos);
+    out_data->wkst = src_data->wkst;
+    out_data->has_alarm = src_data->has_alarm;
+    out_data->updated = src_data->updated;
+
+    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);
+
+    out_data->start = src_data->start;
+    out_data->start_tzid = SAFE_STRDUP(src_data->start_tzid);
+    out_data->due = src_data->due;
+    out_data->due_tzid = SAFE_STRDUP(src_data->due_tzid);
+
+    out_data->organizer_name = SAFE_STRDUP(src_data->organizer_name);
+    out_data->organizer_email = SAFE_STRDUP(src_data->organizer_email);
+    out_data->has_attendee = src_data->has_attendee;
+
+    if( src_data->alarm_list )
+    {
+        GList *alarm_list = src_data->alarm_list;
+        calendar_record_h alarm_child_record;
+
+        while (alarm_list)
+        {
+            calendar_record_h child_clone = NULL;
+            alarm_child_record = (calendar_record_h)alarm_list->data;
+            if (alarm_child_record == NULL)
+            {
+                alarm_list = g_list_next(alarm_list);
+                continue;
+            }
+            if (calendar_record_clone(alarm_child_record, &child_clone) == CALENDAR_ERROR_NONE)
+            {
+                calendar_record_add_child_record((calendar_record_h)out_data,
+                                               CAL_PROPERTY_TODO_CALENDAR_ALARM,child_clone);
+
+            }
+                       alarm_list = g_list_next(alarm_list);
+        }
+
+    }
+
+    if( src_data->attendee_list )
+    {
+        GList * attendee_list = src_data->attendee_list;
+        calendar_record_h attendee_child = NULL;
+
+        while (attendee_list)
+        {
+            calendar_record_h child_clone = NULL;
+            attendee_child = (calendar_record_h)attendee_list->data;
+            if (attendee_child == NULL)
+            {
+                attendee_list = g_list_next(attendee_list);
+                continue;
+            }
+            if (calendar_record_clone(attendee_child, &child_clone) == CALENDAR_ERROR_NONE)
+            {
+
+                calendar_record_add_child_record((calendar_record_h)out_data,
+                        CAL_PROPERTY_TODO_CALENDAR_ATTENDEE,child_clone);
+
+            }
+                       attendee_list = g_list_next(attendee_list);
+        }
+
+    }
+
+    if( src_data->extended_list )
+    {
+        GList * extended_list = src_data->extended_list;
+        calendar_record_h extended = NULL;
+
+        while (extended_list)
+        {
+            calendar_record_h child_clone = NULL;
+            extended = (calendar_record_h)extended_list->data;
+            if (extended == NULL)
+            {
+                extended_list = g_list_next(extended_list);
+                continue;
+            }
+            if (calendar_record_clone(extended, &child_clone) == CALENDAR_ERROR_NONE)
+            {
+
+                calendar_record_add_child_record((calendar_record_h)out_data,
+                        CAL_PROPERTY_TODO_EXTENDED,child_clone);
+
+            }
+            extended_list = g_list_next(extended_list);
+        }
+
+    }
+
+    *out_record = (calendar_record_h)out_data;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_str( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_SUMMARY:
+        *out_str = SAFE_STRDUP(rec->summary);
+        break;
+    case CAL_PROPERTY_TODO_DESCRIPTION:
+        *out_str = SAFE_STRDUP(rec->description);
+        break;
+    case CAL_PROPERTY_TODO_LOCATION:
+        *out_str = SAFE_STRDUP(rec->location);
+        break;
+    case CAL_PROPERTY_TODO_CATEGORIES:
+        *out_str = SAFE_STRDUP(rec->categories);
+        break;
+
+    case CAL_PROPERTY_TODO_UID:
+        *out_str = SAFE_STRDUP(rec->uid);
+        break;
+
+    case CAL_PROPERTY_TODO_BYSECOND:
+        *out_str = SAFE_STRDUP(rec->bysecond);
+        break;
+    case CAL_PROPERTY_TODO_BYMINUTE:
+        *out_str = SAFE_STRDUP(rec->byminute);
+        break;
+    case CAL_PROPERTY_TODO_BYHOUR:
+        *out_str = SAFE_STRDUP(rec->byhour);
+        break;
+    case CAL_PROPERTY_TODO_BYDAY:
+        *out_str = SAFE_STRDUP(rec->byday);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTHDAY:
+        *out_str = SAFE_STRDUP(rec->bymonthday);
+        break;
+    case CAL_PROPERTY_TODO_BYYEARDAY:
+        *out_str = SAFE_STRDUP(rec->byyearday);
+        break;
+    case CAL_PROPERTY_TODO_BYWEEKNO:
+        *out_str = SAFE_STRDUP(rec->byweekno);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTH:
+        *out_str = SAFE_STRDUP(rec->bymonth);
+        break;
+    case CAL_PROPERTY_TODO_BYSETPOS:
+        *out_str = SAFE_STRDUP(rec->bysetpos);
+        break;
+
+    case CAL_PROPERTY_TODO_SYNC_DATA1:
+        *out_str = SAFE_STRDUP(rec->sync_data1);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA2:
+        *out_str = SAFE_STRDUP(rec->sync_data2);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA3:
+        *out_str = SAFE_STRDUP(rec->sync_data3);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA4:
+        *out_str = SAFE_STRDUP(rec->sync_data4);
+        break;
+    case CAL_PROPERTY_TODO_START_TZID:
+        *out_str = SAFE_STRDUP(rec->start_tzid);
+        break;
+    case CAL_PROPERTY_TODO_DUE_TZID:
+        *out_str = SAFE_STRDUP(rec->due_tzid);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_NAME:
+        *out_str = SAFE_STRDUP(rec->organizer_name);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_EMAIL:
+        *out_str = SAFE_STRDUP(rec->organizer_email);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_SUMMARY:
+        *out_str = (rec->summary);
+        break;
+    case CAL_PROPERTY_TODO_DESCRIPTION:
+        *out_str = (rec->description);
+        break;
+    case CAL_PROPERTY_TODO_LOCATION:
+        *out_str = (rec->location);
+        break;
+    case CAL_PROPERTY_TODO_CATEGORIES:
+        *out_str = (rec->categories);
+        break;
+
+    case CAL_PROPERTY_TODO_UID:
+        *out_str = (rec->uid);
+        break;
+
+    case CAL_PROPERTY_TODO_BYSECOND:
+        *out_str = (rec->bysecond);
+        break;
+    case CAL_PROPERTY_TODO_BYMINUTE:
+        *out_str = (rec->byminute);
+        break;
+    case CAL_PROPERTY_TODO_BYHOUR:
+        *out_str = (rec->byhour);
+        break;
+    case CAL_PROPERTY_TODO_BYDAY:
+        *out_str = (rec->byday);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTHDAY:
+        *out_str = (rec->bymonthday);
+        break;
+    case CAL_PROPERTY_TODO_BYYEARDAY:
+        *out_str = (rec->byyearday);
+        break;
+    case CAL_PROPERTY_TODO_BYWEEKNO:
+        *out_str = (rec->byweekno);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTH:
+        *out_str = (rec->bymonth);
+        break;
+    case CAL_PROPERTY_TODO_BYSETPOS:
+        *out_str = (rec->bysetpos);
+        break;
+
+    case CAL_PROPERTY_TODO_SYNC_DATA1:
+        *out_str = (rec->sync_data1);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA2:
+        *out_str = (rec->sync_data2);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA3:
+        *out_str = (rec->sync_data3);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA4:
+        *out_str = (rec->sync_data4);
+        break;
+    case CAL_PROPERTY_TODO_START_TZID:
+        *out_str = (rec->start_tzid);
+        break;
+    case CAL_PROPERTY_TODO_DUE_TZID:
+        *out_str = (rec->due_tzid);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_NAME:
+        *out_str = (rec->organizer_name);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_EMAIL:
+        *out_str = (rec->organizer_email);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_ID:
+        *out_value = (rec->index);
+        break;
+    case CAL_PROPERTY_TODO_CALENDAR_ID:
+        *out_value = (rec->calendar_id);
+        break;
+    case CAL_PROPERTY_TODO_TODO_STATUS:
+        *out_value = (rec->todo_status);
+        break;
+
+    case CAL_PROPERTY_TODO_PRIORITY:
+        *out_value = (rec->priority);
+        break;
+    //sensitivity
+    case CAL_PROPERTY_TODO_SENSITIVITY:
+        *out_value = (rec->sensitivity);
+        break;
+
+    case CAL_PROPERTY_TODO_PROGRESS:
+        *out_value = (rec->progress);
+        break;
+    //is_deleted
+    case CAL_PROPERTY_TODO_IS_DELETED:
+        *out_value = (rec->is_deleted);
+        break;
+    //freq
+    case CAL_PROPERTY_TODO_FREQ:
+        *out_value = (rec->freq);
+        break;
+    //range_type
+    case CAL_PROPERTY_TODO_RANGE_TYPE:
+        *out_value = (rec->range_type);
+        break;
+    //count
+    case CAL_PROPERTY_TODO_COUNT:
+        *out_value = (rec->count);
+        break;
+    //interval
+    case CAL_PROPERTY_TODO_INTERVAL:
+        *out_value = (rec->interval);
+        break;
+    //wkst
+    case CAL_PROPERTY_TODO_WKST:
+        *out_value = (rec->wkst);
+        break;
+
+    //has_alarm
+    case CAL_PROPERTY_TODO_HAS_ALARM:
+        *out_value = (rec->has_alarm);
+        break;
+    case CAL_PROPERTY_TODO_HAS_ATTENDEE:
+        *out_value = (rec->has_attendee);
+        break;
+    case CAL_PROPERTY_TODO_IS_ALLDAY:
+        *out_value = (rec->due.type);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_double( calendar_record_h record, unsigned int property_id, double* out_value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_LATITUDE:
+        *out_value = (rec->latitude);
+        break;
+    case CAL_PROPERTY_TODO_LONGITUDE:
+        *out_value = (rec->longitude);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_CREATED_TIME:
+        *out_value = (rec->created_time);
+        break;
+    case CAL_PROPERTY_TODO_LAST_MODIFIED_TIME:
+        *out_value = (rec->last_mod);
+        break;
+    case CAL_PROPERTY_TODO_COMPLETED_TIME:
+        *out_value = (rec->completed_time);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_START:
+        *out_value = rec->start;
+        break;
+    case CAL_PROPERTY_TODO_DUE:
+        *out_value = rec->due;
+        break;
+    case CAL_PROPERTY_TODO_UNTIL:
+        if (rec->until_type == CALENDAR_TIME_UTIME)
+        {
+            CAL_CALTIME_SET_UTIME(*out_value, rec->until_utime);
+        }
+        else
+        {
+            CAL_CALTIME_SET_DATE(*out_value, rec->until_year,rec->until_month,rec->until_mday);
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_set_str( calendar_record_h record, unsigned int property_id, const char* value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_SUMMARY:
+        CAL_FREE(rec->summary);
+        rec->summary = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_DESCRIPTION:
+        CAL_FREE(rec->description);
+        rec->description = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_LOCATION:
+        CAL_FREE(rec->location);
+        rec->location = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_CATEGORIES:
+        CAL_FREE(rec->categories);
+        rec->categories = SAFE_STRDUP(value);
+        break;
+
+    case CAL_PROPERTY_TODO_UID:
+        CAL_FREE(rec->uid);
+        rec->uid = SAFE_STRDUP(value);
+        break;
+
+    case CAL_PROPERTY_TODO_BYSECOND:
+        CAL_FREE(rec->bysecond);
+        rec->bysecond = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYMINUTE:
+        CAL_FREE(rec->byminute);
+        rec->byminute = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYHOUR:
+        CAL_FREE(rec->byhour);
+        rec->byhour = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYDAY:
+        CAL_FREE(rec->byday);
+        rec->byday = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTHDAY:
+        CAL_FREE(rec->bymonthday);
+        rec->bymonthday = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYYEARDAY:
+        CAL_FREE(rec->byyearday);
+        rec->byyearday = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYWEEKNO:
+        CAL_FREE(rec->byweekno);
+        rec->byweekno = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTH:
+        CAL_FREE(rec->bymonth);
+        rec->bymonth = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_BYSETPOS:
+        CAL_FREE(rec->bysetpos);
+        rec->bysetpos = SAFE_STRDUP(value);
+        break;
+
+    case CAL_PROPERTY_TODO_SYNC_DATA1:
+        CAL_FREE(rec->sync_data1);
+        rec->sync_data1 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA2:
+        CAL_FREE(rec->sync_data2);
+        rec->sync_data2 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA3:
+        CAL_FREE(rec->sync_data3);
+        rec->sync_data3 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA4:
+        CAL_FREE(rec->sync_data4);
+        rec->sync_data4 = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_START_TZID:
+        CAL_FREE(rec->start_tzid);
+        rec->start_tzid = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_DUE_TZID:
+        CAL_FREE(rec->due_tzid);
+        rec->due_tzid = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_NAME:
+        CAL_FREE(rec->organizer_name);
+        rec->organizer_name = SAFE_STRDUP(value);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_EMAIL:
+        CAL_FREE(rec->organizer_email);
+        rec->organizer_email = SAFE_STRDUP(value);
+        break;
+    default:
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_ID:
+        (rec->index) = value;
+        break;
+    case CAL_PROPERTY_TODO_CALENDAR_ID:
+        (rec->calendar_id) = value;
+        break;
+    case CAL_PROPERTY_TODO_TODO_STATUS:
+               switch (value)
+               {
+               case CALENDAR_TODO_STATUS_NONE:
+               case CALENDAR_TODO_STATUS_NEEDS_ACTION:
+               case CALENDAR_TODO_STATUS_COMPLETED:
+               case CALENDAR_TODO_STATUS_IN_PROCESS:
+               case CALENDAR_TODO_STATUS_CANCELED:
+                       (rec->todo_status) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //priority
+    case CAL_PROPERTY_TODO_PRIORITY:
+        (rec->priority) = value;
+        break;
+
+    //sensitivity
+    case CAL_PROPERTY_TODO_SENSITIVITY:
+        (rec->sensitivity) = value;
+        break;
+    case CAL_PROPERTY_TODO_PROGRESS:
+        (rec->progress) = value;
+        break;
+    //is_deleted
+    case CAL_PROPERTY_TODO_IS_DELETED:
+        (rec->is_deleted) = value;
+        break;
+    //freq
+    case CAL_PROPERTY_TODO_FREQ:
+               switch (value)
+               {
+               case CALENDAR_RECURRENCE_NONE:
+               case CALENDAR_RECURRENCE_DAILY:
+               case CALENDAR_RECURRENCE_WEEKLY:
+               case CALENDAR_RECURRENCE_MONTHLY:
+               case CALENDAR_RECURRENCE_YEARLY:
+               (rec->freq) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //range_type
+    case CAL_PROPERTY_TODO_RANGE_TYPE:
+               switch (value)
+               {
+               case CALENDAR_RANGE_UNTIL:
+               case CALENDAR_RANGE_COUNT:
+               case CALENDAR_RANGE_NONE:
+               (rec->range_type) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //count
+    case CAL_PROPERTY_TODO_COUNT:
+        (rec->count) = value;
+        break;
+    //interval
+    case CAL_PROPERTY_TODO_INTERVAL:
+        (rec->interval) = value;
+        break;
+    //wkst
+    case CAL_PROPERTY_TODO_WKST:
+               switch (value)
+               {
+               case CALENDAR_SUNDAY:
+               case CALENDAR_MONDAY:
+               case CALENDAR_TUESDAY:
+               case CALENDAR_WEDNESDAY:
+               case CALENDAR_THURSDAY:
+               case CALENDAR_FRIDAY:
+               case CALENDAR_SATURDAY:
+               (rec->wkst) = value;
+                       break;
+               default:
+                       ERR("invalid parameter (value:%d)", value);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+        break;
+    //has_alarm
+    case CAL_PROPERTY_TODO_HAS_ALARM:
+        (rec->has_alarm) = value;
+        break;
+    case CAL_PROPERTY_TODO_HAS_ATTENDEE:
+        (rec->has_attendee) = value;
+        break;
+    case CAL_PROPERTY_TODO_IS_ALLDAY:
+        (rec->due.type) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_set_double( calendar_record_h record, unsigned int property_id, double value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_LATITUDE:
+        (rec->latitude) = value;
+        break;
+    case CAL_PROPERTY_TODO_LONGITUDE:
+        (rec->longitude) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_set_lli( calendar_record_h record, unsigned int property_id, long long int value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_CREATED_TIME:
+        (rec->created_time) = value;
+        break;
+    case CAL_PROPERTY_TODO_LAST_MODIFIED_TIME:
+        (rec->last_mod) = value;
+        break;
+    case CAL_PROPERTY_TODO_COMPLETED_TIME:
+        (rec->completed_time) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s value )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_START:
+        (rec->start) = value;
+        break;
+    case CAL_PROPERTY_TODO_DUE:
+        (rec->due) = value;
+        break;
+    case CAL_PROPERTY_TODO_UNTIL:
+        (rec->until_type) = value.type;;
+        if(value.type == CALENDAR_TIME_UTIME)
+        {
+            (rec->until_utime) = value.time.utime;
+            (rec->until_year) = 0;
+            (rec->until_month) = 0;
+            (rec->until_mday) = 0;
+        }
+        else
+        {
+            (rec->until_utime) = 0;
+            (rec->until_year) = value.time.date.year;
+            (rec->until_month) = value.time.date.month;
+            (rec->until_mday) = value.time.date.mday ;
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_add_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_CALENDAR_ALARM:
+        rec->alarm_list = g_list_append(rec->alarm_list,child_record);
+        rec->has_alarm = 1;
+        break;
+    case CAL_PROPERTY_TODO_CALENDAR_ATTENDEE:
+        rec->attendee_list = g_list_append(rec->attendee_list,child_record);
+        rec->has_attendee = 1;
+        break;
+    case CAL_PROPERTY_TODO_EXTENDED:
+        rec->extended_list = g_list_append(rec->extended_list,child_record);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_remove_child_record( calendar_record_h record, unsigned int property_id, calendar_record_h child_record )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    //GList* node = NULL;
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_CALENDAR_ALARM:
+        //node = g_list_find(rec->alarm_list,child_record);
+        rec->alarm_list = g_list_remove(rec->alarm_list,child_record);
+        if (g_list_length(rec->alarm_list) == 0)
+        {
+            rec->has_alarm = 0;
+        }
+        break;
+    case CAL_PROPERTY_TODO_CALENDAR_ATTENDEE:
+        rec->attendee_list = g_list_remove(rec->attendee_list,child_record);
+        if (g_list_length(rec->attendee_list) == 0)
+        {
+            rec->has_attendee = 0;
+        }
+        break;
+    case CAL_PROPERTY_TODO_EXTENDED:
+        rec->extended_list = g_list_remove(rec->extended_list,child_record);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_child_record_count( calendar_record_h record, unsigned int property_id , unsigned int* count )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    *count = 0;
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_CALENDAR_ALARM:
+               if (rec->alarm_list)
+               {
+                   *count = g_list_length(rec->alarm_list);
+               }
+        break;
+    case CAL_PROPERTY_TODO_CALENDAR_ATTENDEE:
+        if (rec->attendee_list)
+        {
+            *count = g_list_length(rec->attendee_list);
+        }
+        break;
+    case CAL_PROPERTY_TODO_EXTENDED:
+        if (rec->extended_list)
+        {
+            *count = g_list_length(rec->extended_list);
+        }
+        break;
+    default:
+        *count = 0;
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_get_child_record_at_p( calendar_record_h record, unsigned int property_id, int index, calendar_record_h* child_record )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_CALENDAR_ALARM:
+        *child_record = g_list_nth_data(rec->alarm_list,index);
+        break;
+    case CAL_PROPERTY_TODO_CALENDAR_ATTENDEE:
+        *child_record = g_list_nth_data(rec->attendee_list,index);
+        break;
+    case CAL_PROPERTY_TODO_EXTENDED:
+        *child_record = g_list_nth_data(rec->extended_list,index);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_todo_clone_child_record_list( calendar_record_h record, unsigned int property_id, calendar_list_h* out_list )
+{
+    cal_todo_s *rec = (cal_todo_s*)(record);
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_list_h list;
+    int count = 0;
+
+    ret = calendar_list_create(&list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_list_create fail");
+        return ret;
+    }
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_TODO_CALENDAR_ALARM:
+    {
+        count = g_list_length(rec->alarm_list);
+        if (count <=0 )
+        {
+            calendar_list_destroy(list, true);
+            return CALENDAR_ERROR_NO_DATA;
+        }
+        GList *alarm_list = rec->alarm_list;
+        calendar_record_h alarm_child_record;
+        calendar_record_h alarm_record = NULL;
+        while (alarm_list)
+        {
+            alarm_child_record = (calendar_record_h)alarm_list->data;
+            if (alarm_child_record == NULL)
+            {
+                alarm_list = g_list_next(alarm_list);
+                continue;
+            }
+
+            if ( calendar_record_clone(alarm_child_record,&alarm_record) == CALENDAR_ERROR_NONE )
+            {
+                calendar_list_add(list,alarm_record);
+            }
+            alarm_record = NULL;
+
+            alarm_list = g_list_next(alarm_list);
+        }
+        *out_list = (calendar_list_h)list;
+    }
+    break;
+    case CAL_PROPERTY_TODO_CALENDAR_ATTENDEE:
+    {
+        count = g_list_length(rec->attendee_list);
+        if (count <=0 )
+        {
+            calendar_list_destroy(list, true);
+            return CALENDAR_ERROR_NO_DATA;
+        }
+        GList *attendee_list = rec->attendee_list;
+        calendar_record_h attendee_child_record;
+        calendar_record_h attendee_record = NULL;
+        while (attendee_list)
+        {
+            attendee_child_record = (calendar_record_h)attendee_list->data;
+            if (attendee_child_record == NULL)
+            {
+                attendee_list = g_list_next(attendee_list);
+                continue;
+            }
+
+            if ( calendar_record_clone(attendee_child_record,&attendee_record) == CALENDAR_ERROR_NONE )
+            {
+                calendar_list_add(list,attendee_record);
+            }
+            attendee_record = NULL;
+
+            attendee_list = g_list_next(attendee_list);
+        }
+        *out_list = (calendar_list_h)list;
+    }
+    break;
+    case CAL_PROPERTY_TODO_EXTENDED:
+    {
+        count = g_list_length(rec->extended_list);
+        if (count <=0 )
+        {
+            calendar_list_destroy(list, true);
+            return CALENDAR_ERROR_NO_DATA;
+        }
+        GList *extended_list = rec->extended_list;
+        calendar_record_h child_record;
+        calendar_record_h record = NULL;
+        while (extended_list)
+        {
+            child_record = (calendar_record_h)extended_list->data;
+            if (child_record == NULL)
+            {
+                extended_list = g_list_next(extended_list);
+                continue;
+            }
+
+            if ( calendar_record_clone(child_record,&record) == CALENDAR_ERROR_NONE )
+            {
+                calendar_list_add(list,record);
+            }
+            record = NULL;
+
+            extended_list = g_list_next(extended_list);
+        }
+        *out_list = (calendar_list_h)list;
+    }
+    break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_record_updated_info.c b/common/cal_record_updated_info.c
new file mode 100644 (file)
index 0000000..b4f9efd
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>        //bool
+#include <string.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+
+static int __cal_record_updated_info_create( calendar_record_h* out_record );
+static int __cal_record_updated_info_destroy( calendar_record_h record, bool delete_child );
+static int __cal_record_updated_info_clone( calendar_record_h record, calendar_record_h* out_record );
+static int __cal_record_updated_info_get_int( calendar_record_h record, unsigned int property_id, int* out_value );
+static int __cal_record_updated_info_set_int( calendar_record_h record, unsigned int property_id, int value );
+
+cal_record_plugin_cb_s _cal_record_updated_info_plugin_cb = {
+    .create = __cal_record_updated_info_create,
+    .destroy = __cal_record_updated_info_destroy,
+    .clone = __cal_record_updated_info_clone,
+    .get_str = NULL,
+    .get_str_p = NULL,
+    .get_int = __cal_record_updated_info_get_int,
+    .get_double = NULL,
+    .get_lli = NULL,
+    .get_caltime = NULL,
+    .set_str = NULL,
+    .set_int = __cal_record_updated_info_set_int,
+    .set_double = NULL,
+    .set_lli = NULL,
+    .set_caltime = 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 __cal_record_updated_info_create( calendar_record_h* out_record )
+{
+    cal_updated_info_s *temp = NULL;
+    int ret= CALENDAR_ERROR_NONE, type = 0;
+
+    type = CAL_RECORD_TYPE_UPDATED_INFO;
+
+    temp = (cal_updated_info_s*)calloc(1,sizeof(cal_updated_info_s));
+    retvm_if(NULL == temp, CALENDAR_ERROR_OUT_OF_MEMORY, "malloc(cal_updated_info_s:sch) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    *out_record = (calendar_record_h)temp;
+
+    return ret;
+}
+
+static int __cal_record_updated_info_destroy( calendar_record_h record, bool delete_child )
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_updated_info_s *temp = (cal_updated_info_s*)(record);
+
+    CAL_FREE(temp);
+
+    return ret;
+}
+
+static int __cal_record_updated_info_clone( calendar_record_h record, calendar_record_h* out_record )
+{
+    cal_updated_info_s *out_data = NULL;
+    cal_updated_info_s *src_data = NULL;
+
+    src_data = (cal_updated_info_s*)(record);
+
+    out_data = calloc(1, sizeof(cal_updated_info_s));
+    retvm_if(NULL == out_data, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc(cal_updated_info_s) Failed(%d)", CALENDAR_ERROR_OUT_OF_MEMORY);
+
+    CAL_RECORD_COPY_COMMON(&(out_data->common), &(src_data->common));
+
+    out_data->type = src_data->type;
+    out_data->id = src_data->id;
+    out_data->calendar_id = src_data->calendar_id;
+    out_data->version = src_data->version;
+
+    *out_record = (calendar_record_h)out_data;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_updated_info_get_int( calendar_record_h record, unsigned int property_id, int* out_value )
+{
+    cal_updated_info_s *rec = (cal_updated_info_s*)(record);
+
+    switch( property_id )
+    {
+    case CAL_PROPERTY_UPDATED_INFO_ID:
+        *out_value = (rec->id);
+        break;
+    case CAL_PROPERTY_UPDATED_INFO_CALENDAR_ID:
+        *out_value = (rec->calendar_id);
+        break;
+    case CAL_PROPERTY_UPDATED_INFO_TYPE:
+        *out_value = (rec->type);
+        break;
+    case CAL_PROPERTY_UPDATED_INFO_VERSION:
+        *out_value = (rec->version);
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_record_updated_info_set_int( calendar_record_h record, unsigned int property_id, int value )
+{
+    cal_updated_info_s *rec = (cal_updated_info_s*)(record);
+    switch( property_id )
+    {
+    case CAL_PROPERTY_UPDATED_INFO_ID:
+        (rec->id) = value;
+        break;
+    case CAL_PROPERTY_UPDATED_INFO_CALENDAR_ID:
+        (rec->calendar_id) = value;
+        break;
+    case CAL_PROPERTY_UPDATED_INFO_TYPE:
+        (rec->type) = value;
+        break;
+    case CAL_PROPERTY_UPDATED_INFO_VERSION:
+        (rec->version) = value;
+        break;
+    default:
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_time.cpp b/common/cal_time.cpp
new file mode 100644 (file)
index 0000000..3625e53
--- /dev/null
@@ -0,0 +1,587 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdlib.h>
+#include <unicode/utypes.h>
+#include <unicode/ucal.h>
+#include <unicode/uloc.h>
+#include <unicode/calendar.h>
+#include <unicode/timezone.h>
+#include <unicode/gregocal.h>
+#include <unicode/simpletz.h>
+#include <unicode/ustring.h>
+#include <unicode/strenum.h>
+#include <unicode/ustdio.h>
+#include <unicode/udat.h>
+#include <unicode/rbtz.h>
+
+#include "calendar2.h"
+#include "cal_internal.h"
+#include "cal_typedef.h"
+
+#include "cal_time.h"
+
+#define ULOC_LOCALE_IDENTIFIER_CAPACITY (ULOC_FULLNAME_CAPACITY + 1 + ULOC_KEYWORD_AND_VALUES_CAPACITY)
+#define uprv_strncpy(dst, src, size) U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size)
+
+#define ms2sec(ms) (long long int)(ms / 1000.0)
+#define sec2ms(s) (s * 1000.0)
+
+int _cal_time_is_registered_tzid(const char *tzid)
+{
+       int is_found = 0;
+       int i;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (NULL == tzid)
+       {
+               ERR("tzid is NULL");
+               return is_found;
+       }
+
+       StringEnumeration* s = TimeZone::createEnumeration();
+       int32_t s_count = s->count(ec);
+
+       for (i = 0; i < s_count; i++)
+       {
+               char buf[128] = {0};
+               const UnicodeString *unicode_tzid = s->snext(ec);
+               unicode_tzid->extract(buf, sizeof(buf), NULL, ec);
+               if (!strncmp(tzid, buf, strlen(buf)))
+               {
+                       is_found = 1;
+                       break;
+               }
+       }
+       delete s;
+       return is_found;
+}
+
+int _cal_time_get_timezone_from_table(const char *tzid, calendar_record_h *timezone, int *timezone_id)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       int count = 0;
+       int _timezone_id = 0;
+       calendar_record_h _timezone = NULL;
+       calendar_filter_h filter = NULL;
+       calendar_query_h query = NULL;
+       calendar_list_h list = NULL;
+
+       ret = calendar_connect();
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_connect() failed");
+               return ret;
+       }
+
+       ret = calendar_query_create(_calendar_timezone._uri, &query);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_CONNECT;
+
+       ret = calendar_filter_create(_calendar_timezone._uri, &filter);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_QUERY;
+
+       ret = calendar_filter_add_str(filter, _calendar_timezone.standard_name, CALENDAR_MATCH_EXACTLY, tzid);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_FILTER;
+
+       ret = calendar_query_set_filter(query, filter);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_FILTER;
+
+       ret = calendar_db_get_records_with_query(query, 0, 0, &list);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_LIST;
+
+       ret = calendar_list_get_count(list, &count);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_LIST;
+       DBG("tzid count(%d)", count);
+       if (count <= 0)
+       {
+               DBG("No count");
+               calendar_list_destroy(list, false);
+               calendar_filter_destroy(filter);
+               calendar_query_destroy(query);
+               calendar_disconnect();
+               return CALENDAR_ERROR_NONE;
+       }
+
+       ret = calendar_list_first(list);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_LIST;
+
+       ret = calendar_list_get_current_record_p(list, &_timezone);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_LIST;
+
+       ret = calendar_record_get_int(_timezone, _calendar_timezone.id, &_timezone_id);
+       if (CALENDAR_ERROR_NONE != ret) goto ERROR_LIST;
+
+       calendar_list_destroy(list, false);
+       calendar_filter_destroy(filter);
+       calendar_query_destroy(query);
+       calendar_disconnect();
+
+       if (timezone)
+       {
+               *timezone = _timezone;
+       }
+       else
+       {
+               calendar_record_destroy(_timezone, true);
+       }
+       if (timezone_id) *timezone_id = _timezone_id;
+
+       return CALENDAR_ERROR_NONE;
+
+ERROR_LIST:
+       ERR("list error");
+       calendar_list_destroy(list, true);
+ERROR_FILTER:
+       ERR("filter error");
+       calendar_filter_destroy(filter);
+ERROR_QUERY:
+       ERR("queryerror");
+       calendar_query_destroy(query);
+ERROR_CONNECT:
+       calendar_disconnect();
+
+       return ret;
+}
+
+static int __cal_time_get_like_utzid(UChar *utzid, int len, const char *tzid, calendar_record_h timezone, char **like_tzid)
+{
+       int gmtoffset;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (NULL == timezone)
+       {
+               ERR("Invalid parameter: timezone is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       // make utzid
+       UnicodeString zoneStrID;
+       int32_t l = (len < 0 ? u_strlen(utzid) : len);
+       zoneStrID.setTo((UBool)(len < 0), utzid, l); /* temporary read-only alias */
+
+       // make simple timezone
+       cal_timezone_s *tz = (cal_timezone_s *)timezone;
+       gmtoffset = sec2ms(tz->tz_offset_from_gmt * 60);
+
+       if (tz->day_light_bias == 0)
+       {
+               char buf[128] = {0};
+               snprintf(buf, sizeof(buf), "ETC/GMT%c%d",
+                               gmtoffset < 0 ? '-' : '+',
+                               tz->tz_offset_from_gmt / 60);
+               DBG("No dayligit, set like tzid[%s]", buf);
+               *like_tzid = strdup(buf);
+               return CALENDAR_ERROR_NONE;
+       }
+
+       DBG("Try to find like tzid with daylight savings");
+       SimpleTimeZone *stz = new SimpleTimeZone(
+                       sec2ms(tz->tz_offset_from_gmt * 60),
+                       zoneStrID,
+                       tz->day_light_start_month -1,
+                       tz->day_light_start_position_of_week,
+                       tz->day_light_start_day,
+                       sec2ms(tz->day_light_start_hour * 3600),
+                       tz->std_start_month -1,
+                       tz->std_start_position_of_week,
+                       tz->std_start_day,
+                       sec2ms(tz->std_start_hour * 3600),
+                       sec2ms(tz->day_light_bias * 60),
+                       ec);
+
+       int i, j;
+       UDate now = Calendar::getNow();
+       TimeZoneTransition trans;
+       UDate stzudate[5];
+       int32_t stzrawoff[4];
+       int32_t stzdstoff[4];
+       stzudate[0] = now;
+       DBG("tzid[%s]", tzid);
+       for (i = 0; i < 4; i++) // get 4 date: dst begin & end, std begin & end
+       {
+               stz->getPreviousTransition(stzudate[i], (UBool)false, trans);
+               stz->getOffset(stzudate[i], (UBool)true, stzrawoff[i], stzdstoff[i], ec);
+               stzudate[i +1] = trans.getTime();
+               DBG("(%lld)(%d)(%d)", ms2sec(stzudate[i +1]), stzrawoff[i], stzdstoff[i]);
+       }
+       delete stz;
+
+       // extract from all
+       int32_t rawoff;
+       int32_t dstoff;
+       int32_t s_count;
+       int is_found = 0;
+       char *_like_tzid = NULL;
+       UDate udate;
+       UnicodeString canonicalID, tmpCanonical;
+       StringEnumeration* s = TimeZone::createEnumeration(gmtoffset);
+       s_count = s->count(ec);
+
+       DBG("Has count(%d) with the same gmtoffset(%d)", s_count, gmtoffset);
+       if (s_count == 0)
+       {
+               DBG("No count matched");
+               return -1;
+       }
+
+       for (i = 0; i < s_count; i++)
+       {
+               const UnicodeString *unicode_tzid = s->snext(ec);
+               TimeZone *_timezone = TimeZone::createTimeZone(*unicode_tzid);
+
+               if (_timezone->getDSTSavings() != (gmtoffset))
+               {
+                       delete _timezone;
+                       continue;
+               }
+
+               RuleBasedTimeZone *rule = (RuleBasedTimeZone *)_timezone;
+               udate = now;
+               for (j = 0; j < 4; j++)
+               {
+                       rule->getPreviousTransition(udate, (UBool)false, trans);
+                       rule->getOffset(udate, (UBool)true, rawoff, dstoff, ec);
+                       udate = trans.getTime();
+                       DBG("(%lld)(%d)(%d)", ms2sec(udate), rawoff, dstoff);
+
+                       if (udate == stzudate[i+1] && rawoff == stzrawoff[i] && dstoff == stzdstoff[i])
+                       {
+                               DBG("Found matched");
+                               is_found = 1;
+                               break;
+                       }
+               }
+
+               if (is_found)
+               {
+                       _like_tzid = (char *)calloc(unicode_tzid->length() +1, sizeof(char));
+                       for (i = 0; i < unicode_tzid->length(); i++)
+                       {
+                               _like_tzid[i] = unicode_tzid->charAt(i);
+                       }
+                       DBG("Found and set like tzid[%s]", _like_tzid);
+                       *like_tzid = _like_tzid;
+                       delete _timezone;
+                       break;
+               }
+
+               delete _timezone;
+       }
+       delete s;
+       return CALENDAR_ERROR_NONE;
+}
+
+UCalendar *_cal_time_get_ucal(const char *tzid, int wkst)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       char *like_tzid = NULL;
+       UCalendar *ucal = NULL;
+       UErrorCode status = U_ZERO_ERROR;
+       UChar *utzid = NULL;
+
+       if (tzid == NULL)
+       {
+               DBG("tzid is NULL so set gmt");
+               tzid = CAL_TZID_GMT;
+       }
+
+       utzid = (UChar*)calloc(strlen(tzid) + 1, sizeof(UChar));
+       if (utzid == NULL)
+       {
+               ERR("Failed to calloc");
+               return NULL;
+       }
+       u_uastrcpy(utzid, tzid);
+
+       if (_cal_time_is_registered_tzid(tzid) == 0)
+       {
+               DBG("Not registered tzid so try to find from timezone table");
+
+               calendar_record_h timezone = NULL;
+               ret = _cal_time_get_timezone_from_table(tzid, &timezone, NULL);
+               if (ret == CALENDAR_ERROR_NONE)
+               {
+                       DBG("Found something in the timezone table");
+                       ret = __cal_time_get_like_utzid(utzid, u_strlen(utzid), tzid, timezone, &like_tzid);
+                       if (ret != CALENDAR_ERROR_NONE)
+                       {
+                               DBG("Failed to find matched tzid with the found tzid, so set GMT");
+                               like_tzid = strdup(CAL_TZID_GMT);
+                       }
+                       DBG("Found matched tzid with the found tzid[%s]", like_tzid);
+               }
+               else
+               {
+                       ERR("Failed to find timezone from table with this tzid[%s], so set gmt", tzid);
+                       like_tzid = strdup(CAL_TZID_GMT);
+               }
+               CAL_FREE(utzid);
+
+               DBG("[%s]", like_tzid);
+               utzid = (UChar*)calloc(strlen(like_tzid) + 1, sizeof(UChar));
+               if (utzid == NULL)
+               {
+                       ERR("Failed to calloc");
+                       CAL_FREE(like_tzid);
+                       return NULL;
+               }
+               u_uastrcpy(utzid, like_tzid);
+               CAL_FREE(like_tzid);
+       }
+       else
+       {
+               DBG("This tzid is valid");
+       }
+
+       // get ucal
+       ucal = ucal_open(utzid, u_strlen(utzid), "en_US", UCAL_TRADITIONAL, &status);
+       if (U_FAILURE(status)) {
+               ERR("ucal_open failed (%s)", u_errorName(status));
+               CAL_FREE(utzid);
+               return NULL;
+       }
+       CAL_FREE(utzid);
+
+       if (wkst >= CALENDAR_SUNDAY && wkst <= CALENDAR_SATURDAY)
+       {
+               DBG("set wkst(%d)", wkst);
+               ucal_setAttribute(ucal, UCAL_FIRST_DAY_OF_WEEK, wkst);
+       }
+
+       return ucal;
+}
+
+int _cal_time_get_like_tzid(const char *tzid, calendar_record_h timezone, char **like_tzid)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       UChar *utzid = NULL;
+
+       if (NULL == timezone)
+       {
+               ERR("Invalid parameter: timezone is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       if (tzid == NULL)
+       {
+               DBG("tzid is NULL so set gmt");
+               tzid = CAL_TZID_GMT;
+       }
+
+       utzid = (UChar*)calloc(strlen(tzid) + 1, sizeof(UChar));
+       if (utzid == NULL)
+       {
+               ERR("Failed to calloc");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       u_uastrcpy(utzid, tzid);
+
+       ret = __cal_time_get_like_utzid(utzid, u_strlen(utzid), tzid, timezone, like_tzid);
+       if (ret != CALENDAR_ERROR_NONE)
+       {
+               DBG("Failed to find from timezone table, so set GMT");
+               *like_tzid = strdup(CAL_TZID_GMT);
+       }
+       CAL_FREE(utzid);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+void _cal_time_set_caltime(UCalendar *ucal, calendar_time_s *ct)
+{
+       UErrorCode status = U_ZERO_ERROR;
+
+       switch (ct->type)
+       {
+       case CALENDAR_TIME_UTIME:
+               ucal_setMillis(ucal, sec2ms(ct->time.utime), &status);
+               retm_if(U_FAILURE(status), "ucal_setMillis() failed(%s)",
+                               u_errorName(status));
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               ucal_setDate(ucal,
+                               ct->time.date.year,
+                               ct->time.date.month -1,
+                               ct->time.date.mday,
+                               &status);
+               retm_if(U_FAILURE(status), "ucal_setMillis() failed(%s)",
+                               u_errorName(status));
+               break;
+
+       default:
+               ERR("Invalid dtstart type. Current time is used in default");
+       }
+}
+
+char * _cal_time_extract_by(const char *tzid, int wkst, calendar_time_s *ct, int field)
+{
+       int vali;
+       char buf[8] = {0};
+       char weeks[7][3] = {"SU", "MO", "TU", "WE", "TH", "FR", "SA"};
+       UCalendar *ucal = NULL;
+       UErrorCode status = U_ZERO_ERROR;
+
+       ucal = _cal_time_get_ucal(tzid, wkst);
+       _cal_time_set_caltime(ucal, ct);
+
+       switch (field)
+       {
+       case CAL_DATE:
+               vali = ucal_get(ucal, UCAL_DATE, &status);
+               snprintf(buf, sizeof(buf), "%d", vali);
+               break;
+
+       case CAL_DAY_OF_WEEK:
+               vali = ucal_get(ucal, UCAL_DAY_OF_WEEK, &status);
+               snprintf(buf, sizeof(buf), "%s", weeks[vali - 1]);
+               break;
+
+       default:
+               break;
+
+       }
+       return strdup(buf);
+}
+
+char * _cal_time_convert_ltos(const char *tzid, long long int lli)
+{
+       int y, mon, d, h, min, s;
+       char buf[32] = {0};
+       UCalendar *ucal;
+       UErrorCode status = U_ZERO_ERROR;
+
+       if (tzid == NULL)
+       {
+               DBG("tzid is NULL so set gmt");
+               tzid = CAL_TZID_GMT;
+       }
+
+       ucal = _cal_time_get_ucal(tzid, -1);
+       ucal_setMillis(ucal, sec2ms(lli), &status);
+       if (U_FAILURE(status)) {
+               ERR("ucal_setMillis failed (%s)", u_errorName(status));
+               return NULL;
+       }
+
+       y = ucal_get(ucal, UCAL_YEAR, &status);
+       mon = ucal_get(ucal, UCAL_MONTH, &status) + 1;
+       d = ucal_get(ucal, UCAL_DATE, &status);
+       h = ucal_get(ucal, UCAL_HOUR_OF_DAY, &status);
+       min = ucal_get(ucal, UCAL_MINUTE, &status);
+       s = ucal_get(ucal, UCAL_SECOND, &status);
+
+       if (!strncmp(tzid, CAL_TZID_GMT, strlen(CAL_TZID_GMT)))
+       {
+               snprintf(buf, sizeof(buf), "%04d%02d%02dT%02d%02d%02dZ",
+                       y, mon, d, h, min, s);
+       }
+       else
+       {
+               snprintf(buf, sizeof(buf), "%04d%02d%02dT%02d%02d%02d",
+                       y, mon, d, h, min, s);
+       }
+
+       ucal_close(ucal);
+
+       return strdup(buf);
+}
+
+long long int _cal_time_convert_itol(const char *tzid, int y, int mon, int d, int h, int min, int s)
+{
+       long long int lli;
+       UCalendar *ucal;
+       UErrorCode status = U_ZERO_ERROR;
+
+       ucal = _cal_time_get_ucal(tzid, -1);
+
+       ucal_set(ucal, UCAL_YEAR, y);
+       ucal_set(ucal, UCAL_MONTH, mon -1);
+       ucal_set(ucal, UCAL_DATE, d);
+       ucal_set(ucal, UCAL_HOUR_OF_DAY, h);
+       ucal_set(ucal, UCAL_MINUTE, min);
+       ucal_set(ucal, UCAL_SECOND, s);
+       lli = ms2sec(ucal_getMillis(ucal, &status));
+
+       ucal_close(ucal);
+       return lli;
+}
+
+long long int _cal_time_convert_stol(char *tzid, char *datetime)
+{
+       int y, mon, d, h, min, s;
+       char t, z;
+
+       if (datetime == NULL || strlen(datetime) == 0) {
+               ERR("Invalid argument");
+               return -1;
+       }
+
+       sscanf(datetime,  "%4d%2d%2d%c%2d%2d%2d%c",
+                       &y, &mon, &d, &t, &h, &min, &s, &z);
+
+       return _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+}
+
+int _cal_time_ltoi(char *tzid, long long int lli, int *year, int *month, int *mday)
+{
+       UCalendar *ucal;
+       UErrorCode status = U_ZERO_ERROR;
+
+       ucal = _cal_time_get_ucal(tzid, 1);
+       ucal_setMillis(ucal, sec2ms(lli), &status);
+
+       if (year) *year = ucal_get(ucal, UCAL_YEAR, &status);
+       if (month) *month = ucal_get(ucal, UCAL_MONTH, &status) +1;
+       if (mday) *mday = ucal_get(ucal, UCAL_DATE, &status);
+
+       ucal_close(ucal);
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_time_ltoi2(char *tzid, long long int lli, int *nth, int *wday)
+{
+       UCalendar *ucal;
+       UErrorCode status = U_ZERO_ERROR;
+
+       ucal = _cal_time_get_ucal(tzid, 1);
+       ucal_setMillis(ucal, sec2ms(lli), &status);
+
+       if (wday)  *wday = ucal_get(ucal, UCAL_DAY_OF_WEEK, &status);
+       if (nth)
+       {
+               int temp = 0;
+               int temp2 = 0;
+               temp = ucal_get(ucal, UCAL_DAY_OF_WEEK_IN_MONTH, &status);
+               ucal_add(ucal, UCAL_DATE, 7, &status);
+               temp2 = ucal_get(ucal, UCAL_DAY_OF_WEEK_IN_MONTH, &status);
+               DBG("temp(%d) temp2(%d)", temp, temp2);
+               *nth = temp2 == 1 ? -1 : temp;
+       }
+
+       ucal_close(ucal);
+       return CALENDAR_ERROR_NONE;
+}
+
+long long int _cal_time_get_now(void)
+{
+       return ms2sec(ucal_getNow());
+}
+
diff --git a/common/cal_time.h b/common/cal_time.h
new file mode 100644 (file)
index 0000000..8281ea1
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_TIME_H__
+#define __CALENDAR_SVC_TIME_H__
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <unicode/ucal.h>
+#include <unicode/ustring.h>
+#include <unicode/ustdio.h>
+#include <unicode/udat.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int _cal_time_is_registered_tzid(const char *tzid);
+UCalendar *_cal_time_get_ucal(const char *tzid, int wkst);
+char * _cal_time_extract_by(const char *tzid, int wkst, calendar_time_s *ct, int field);
+char * _cal_time_convert_ltos(const char *tzid, long long int lli);
+long long int _cal_time_convert_itol(const char *tzid, int y, int m, int d, int h, int min, int s);
+long long int _cal_time_convert_stol(char *tzid, char *datetime);
+int _cal_time_ltoi(char *tzid, long long int lli, int *year, int *month, int *mday);
+int _cal_time_ltoi2(char *tzid, long long int lli, int *nth, int *wday);
+long long int _cal_time_get_now(void);
+int _cal_time_get_timezone_from_table(const char *tzid, calendar_record_h *timezone, int *timezone_id);
+int _cal_time_get_like_tzid(const char *tzid, calendar_record_h timezone, char **like_tzid);
+
+enum cal_extract_field {
+       CAL_DAY_OF_WEEK,
+       CAL_DATE,
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __CALENDAR_SVC_TIME_H__
diff --git a/common/cal_typedef.h b/common/cal_typedef.h
new file mode 100755 (executable)
index 0000000..9742949
--- /dev/null
@@ -0,0 +1,551 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_TYPEDEF_H__
+#define __CALENDAR_SVC_TYPEDEF_H__
+
+#include <glib.h>
+#include <complex.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include "cal_record.h"
+
+#define CAL_TZID_GMT "Etc/GMT"
+#define CAL_NOTI_EVENT_CHANGED "/opt/usr/data/calendar-svc/.CALENDAR_SVC_EVENT_CHANGED"
+#define CAL_NOTI_TODO_CHANGED "/opt/usr/data/calendar-svc/.CALENDAR_SVC_TODO_CHANGED"
+#define CAL_NOTI_CALENDAR_CHANGED "/opt/usr/data/calendar-svc/.CALENDAR_SVC_CALENDAR_CHANGED"
+
+/**
+ * @enum cal_priority_e
+ * This enumeration defines priority for todo data.
+ */
+typedef enum
+{
+       CAL_PRIORITY_LOW,       /**< priority low */
+       CAL_PRIORITY_MID,       /**< priority middle */
+       CAL_PRIORITY_HIGH       /**< priority high */
+}cal_priority_e;
+
+///////////calendar-svc-provider.h
+// 우선 기존 동작되는 define, enum 을 가져와서 정리.. 향후 calendar_types.h 로 오픈되어야 하는것과 동일 사용
+
+#define LOCAL_ACCOUNT_ID -1
+
+#define CAL_INVALID_ID                         (-1)
+
+/**
+ * This enumeration defines lart type.
+ */
+typedef enum
+{
+       CAL_ALERT_MELODY = 0,                             /**< alarm type is melody */
+       CAL_ALERT_MUTE,                                           /**< alarm type is mute */
+       CAL_ALERT_INCREASING_MELODY,              /**< alarm type is increasing melody */
+       CAL_ALERT_VIBRATION,                               /**< alarm type is vibrate */
+       CAL_ALERT_VIBRATION_THEN_MELODY,          /**< alarm type is vibrate then melody */
+       CAL_ALERT_VIBMELODY,                               /**< alarm type is melody with vibrate */
+       CAL_ALERT_VIB_INCREASING_MELODY         /**< alarm type is increasing melody */
+} cal_alert_type_e;
+/**
+ * This enumeration defines Remind Tick Unit for schedule.
+ * Ex. remindTick = 1, remindTickUnit = CAL_SCH_TIME_UNIT_MIN, Organizer alarms
+ * 1 minute before schedule starting time.
+ */
+typedef enum /* use with *60 */
+{
+       CAL_SCH_TIME_UNIT_OFF = -1, /**< off */
+       CAL_SCH_TIME_UNIT_MIN = 1, /**< Minute */
+       CAL_SCH_TIME_UNIT_HOUR = 60, /**< Hour 60 * 60 */
+       CAL_SCH_TIME_UNIT_DAY = 1440, /**< Day 60 * 60 *24 */
+       CAL_SCH_TIME_UNIT_WEEK = 10080, /**< Week DAY * 7 */
+       CAL_SCH_TIME_UNIT_MONTH,        /**< Month - will be removed*/
+       CAL_SCH_TIME_UNIT_SPECIFIC  /**< using alarm time */
+} cal_sch_remind_tick_unit_e;
+
+typedef enum
+{
+    CAL_SCH_TYPE_NONE=0,           /**< None type */
+    CAL_SCH_TYPE_EVENT,    /**< schedule event type */
+    CAL_SCH_TYPE_TODO,     /**< task event type */
+    CAL_SCH_TYPE_MAX,      /**< max type */
+} cal_sch_type_e;
+
+/*
+enum cal_freq {
+       CAL_FREQ_ONCE = 0x0,
+       CAL_FREQ_YEARLY,
+       CAL_FREQ_MONTHLY,
+       CAL_FREQ_WEEKLY,
+       CAL_FREQ_DAILY,
+       CAL_FREQ_HOURLY,
+       CAL_FREQ_MINUTELY,
+       CAL_FREQ_SECONDLY,
+};
+*/
+/////////////////
+
+
+/**
+ * This structure defines schedule information.
+ */
+typedef struct
+{
+       cal_record_s common;
+       int index;                              /**< Record index */
+       int calendar_id;
+
+       char *summary;                  /**< Summary, appointment, task: subject, birthday:Name */
+       char *description;              /**< Description,appointment, task: description, anniversary,holiday:occasion*/
+       char *location;                 /**< Location */
+       char *categories;
+       char *exdate;
+
+       calendar_event_status_e event_status;           /**< current task status */
+       cal_priority_e priority;                /**< Priority */
+       int timezone;                   /**< timezone of task */
+
+       int contact_id;                 /**< contact id for birthday in contact list */
+
+       int busy_status;                /**< ACS, G : Flag of busy or not */
+       int sensitivity;                /**< ACS, G : The sensitivity (public, private, confidential). #cal_visibility_type_t*/
+       int meeting_status;             /**< ACS, G : The status of the meeting. */
+       char *uid;                              /**< ACS, G : Unique ID of the meeting item */
+       char *organizer_name;           /**< ACS, G : Name of organizer(author) */
+       char *organizer_email;  /**< ACS, G : Email of organizer */
+
+       int original_event_id;        /**< original event id for recurrency exception */
+       double latitude;
+       double longitude;
+       int email_id;
+       //int availability;
+       long long int created_time;
+       //long long int completed_time;
+       //int progress;
+       int is_deleted; /**< for sync */
+       //int duration;
+       long long int last_mod;
+       //int has_rrule;  //int rrule_id;
+       int freq;
+       int range_type;
+       int until_type;
+       long long int until_utime;
+       int until_year;
+       int until_month;
+       int until_mday;
+       int count;
+       int interval;
+       char *bysecond;
+       char *byminute;
+       char *byhour;
+       char *byday;
+       char *bymonthday;
+       char *byyearday;
+       char *byweekno;
+       char *bymonth;
+       char *bysetpos;
+       int wkst;
+       char *recurrence_id;
+       char *rdate;
+       int has_attendee;
+       int has_alarm;
+       int system_type;
+       long updated;
+       char *sync_data1;
+       char *sync_data2;
+       char *sync_data3;
+       char *sync_data4;
+
+       calendar_time_s start;
+       char* start_tzid;
+       calendar_time_s end;
+       char* end_tzid;
+       GList *alarm_list;
+       GList *attendee_list;   /**< collection of attendee */
+
+       GList *exception_list;
+       GList *extended_list;
+}cal_event_s;
+
+typedef struct
+{
+       cal_record_s common;
+       int index;
+       int calendar_id;
+       char *summary;
+       char *description;
+       char *location;
+       char *categories;
+       calendar_todo_status_e todo_status;
+       cal_priority_e priority;
+       int sensitivity;
+       char *uid;
+       double latitude;
+       double longitude;
+       long long int created_time;
+       long long int completed_time;
+       int progress;
+       int is_deleted; /**< for sync */
+       long long int last_mod;
+       //int has_rrule;  //int rrule_id;
+       int freq;
+       int range_type;
+       int until_type;
+       long long int until_utime;
+       int until_year;
+       int until_month;
+       int until_mday;
+       int count;
+       int interval;
+       char *bysecond;
+       char *byminute;
+       char *byhour;
+       char *byday;
+       char *bymonthday;
+       char *byyearday;
+       char *byweekno;
+       char *bymonth;
+       char *bysetpos;
+       int wkst;
+       int has_alarm;
+       long updated;
+       char *sync_data1;
+       char *sync_data2;
+       char *sync_data3;
+       char *sync_data4;
+       calendar_time_s start;
+       char* start_tzid;
+       calendar_time_s due;
+       char* due_tzid;
+       GList *alarm_list;
+    char *organizer_name;
+    char *organizer_email;
+    int has_attendee;
+    GList *attendee_list;
+    GList *extended_list;
+}cal_todo_s;
+
+typedef struct
+{
+       int freq;
+       int range_type;
+       int until_type;
+       long long int until_utime;
+       int until_year;
+       int until_month;
+       int until_mday;
+       int count;
+       int interval;
+       char *bysecond;
+       char *byminute;
+       char *byhour;
+       char *byday;
+       char *bymonthday;
+       char *byyearday;
+       char *byweekno;
+       char *bymonth;
+       char *bysetpos;
+       int wkst;
+}cal_rrule_s;
+
+/**
+ * This structure defines participant information of a meetting.
+ * ical: cutype, member, role, partstat, rsvp, delto, delfrom, sentby, cn,  dir, language
+ */
+typedef struct
+{
+       cal_record_s common;
+       int event_id;
+       char *attendee_number;
+       int attendee_type;
+       int attendee_ct_index;
+       char *attendee_uid;
+       //int is_deleted;
+
+       /* ical spec from here */
+       char *attendee_group;   /* cutype */
+       char *attendee_email;   /* member */
+       int attendee_role;              /* role */
+       int attendee_status;    /* partstat: ACCEPTED, DECLINED.. */
+       int attendee_rsvp;              /* rsvp */
+       char *attendee_delegate_uri;    /* delfrom */
+       char *attendee_delegator_uri;   /* delto */
+       /* sentby */
+       char *attendee_name;    /* cn */
+
+}cal_attendee_s;
+
+/**
+ * This structure defines exception information of alarm.
+ */
+typedef struct
+{
+       cal_record_s common;
+       int alarm_id;                   /**< Alarm id */
+       int event_id;
+       cal_alert_type_e alarm_type;                    /**< Alert type(see 'cal_alert_type_t') */
+       int is_deleted;
+
+       /* audio */
+       /* -- trigger */
+       long long int alarm_time;
+       int remind_tick;
+       int remind_tick_unit;
+       /* --attach */
+       char *alarm_tone;                       /**< Alert Sound File Name */
+
+       /* display */
+       char *alarm_description;                        /**< Alert description */
+
+
+       /* email */
+
+}cal_alarm_s;
+
+//This is the calendar schema
+typedef struct
+{
+       cal_record_s common;
+       int index;
+       int store_type;
+       char *uid;
+       long updated;
+       char *name;
+       char *description;
+       char *color;
+       char *location;
+       int visibility;
+       int sync_event;
+       int is_deleted;
+       int account_id;
+       char *sync_data1;
+       char *sync_data2;
+       char *sync_data3;
+       char *sync_data4;
+} cal_calendar_s;
+
+
+/* type for timezone information save */
+typedef struct
+{
+       cal_record_s common;
+       int index;
+       int tz_offset_from_gmt;
+
+       char *standard_name;
+       int std_start_month;
+       int std_start_position_of_week;
+       int std_start_day;
+       int std_start_hour;
+       int standard_bias;
+
+       char *day_light_name;
+       int day_light_start_month;
+       int day_light_start_position_of_week;
+       int day_light_start_day;
+       int day_light_start_hour;
+       int day_light_bias;
+       int calendar_id;
+} cal_timezone_s;
+
+typedef struct
+{
+       cal_record_s common;
+       int event_id;
+       int calendar_id;
+       int dtstart_type;
+       long long int dtstart_utime;
+       int dtend_type;
+       long long int dtend_utime;
+       char *summary;
+       char *description;
+       char *location;
+       int busy_status;
+       int event_status;
+       int priority;
+       int sensitivity;
+       int has_rrule;  //rrule_id;
+       double latitude;
+       double longitude;
+       int has_alarm;
+       int original_event_id;
+       long long int last_mod;
+} cal_instance_normal_s;
+
+typedef struct
+{
+       cal_record_s common;
+       int event_id;
+       int calendar_id;
+       int dtstart_type;
+       int dtstart_year;
+       int dtstart_month;
+       int dtstart_mday;
+       int dtend_type;
+       int dtend_year;
+       int dtend_month;
+       int dtend_mday;
+       char *summary;
+       char *description;
+       char *location;
+       int busy_status;
+       int event_status;
+       int priority;
+       int sensitivity;
+       int has_rrule;  //rrule_id;
+       double latitude;
+       double longitude;
+       int has_alarm;
+       int original_event_id;
+       long long int last_mod;
+} cal_instance_allday_s;
+
+/*
+typedef struct
+{
+       int index;
+       int calendar_id;
+       int dtstart_type;
+       long long int dtstart_utime;
+       int dtend_type;
+       long long int dtend_utime;
+       long long int alarm_utime;
+       int alarm_id;
+}cal_instance_normal_alarm_s;
+*/
+
+typedef struct
+{
+       cal_record_s common;
+       int type;
+       int id;
+       int calendar_id;
+       int version;
+}cal_updated_info_s;
+
+typedef struct {
+       int count;
+       GList *record;
+       GList *cursor;
+} cal_list_s;
+
+typedef enum
+{
+       CAL_NOTI_TYPE_EVENT = 0x0,
+       CAL_NOTI_TYPE_TODO,
+       CAL_NOTI_TYPE_CALENDAR,
+}cal_noti_type_e;
+
+typedef struct{
+    unsigned int property_id;
+    const char* fields;               // DB field
+}cal_property_info_s;
+
+typedef enum {
+    CAL_FILTER_STR,
+    CAL_FILTER_INT,
+    CAL_FILTER_DOUBLE,
+    CAL_FILTER_LLI,
+    CAL_FILTER_CALTIME,
+    CAL_FILTER_COMPOSITE,
+}cal_filter_type_e;
+
+typedef struct  {
+    int filter_type;     // composite
+    //bool embedded;
+}cal_filter_s;
+
+typedef struct {
+    int filter_type;
+    //bool embedded;
+    char *view_uri;
+    GSList *filter_ops; //calendar_filter_operator_e op;
+    GSList *filters;    //calendar_filter_h l_filter;
+    cal_property_info_s *properties;
+    int property_count;
+}cal_composite_filter_s;
+
+typedef struct  {
+    int filter_type;     //cal_filter_type_e
+    int property_id;
+    int match;              //calendar_match_str_flag_e or calendar_match_int_flag_e
+    union {
+        int i;
+        char *s;
+        double d;
+        long long int lli;
+        calendar_time_s caltime;
+    }value;
+}cal_attribute_filter_s;
+
+typedef struct  {
+    char* view_uri;
+    //GSList *filter_ops;
+    //GSList *filters;
+    cal_composite_filter_s* filter;
+    int projection_count;
+    unsigned int *projection;
+    int sort_property_id;
+    bool asc;
+    cal_property_info_s *properties;
+    int property_count;
+    bool distinct;
+}cal_query_s;
+
+#define CAL_CALTIME_SET_UTIME(dest, src_utime) do {\
+    (dest).type = CALENDAR_TIME_UTIME; \
+    (dest).time.utime = src_utime; \
+} while(0)
+
+#define CAL_CALTIME_SET_DATE(dest, src_year, src_month, src_mday) do {\
+    (dest).type = CALENDAR_TIME_LOCALTIME; \
+    (dest).time.date.year = src_year; \
+    (dest).time.date.month = src_month; \
+    (dest).time.date.mday = src_mday; \
+} while(0)
+
+typedef struct {
+    int property_id;
+    union {
+        int i;
+        char *s;
+        double d;
+        long long int lli;
+        calendar_time_s caltime;
+    }value;
+}cal_search_value_s;
+
+typedef struct {
+    cal_record_s common;
+    GSList *values;
+}cal_search_s;
+
+typedef struct {
+    cal_record_s common;
+    int id;
+    int record_id;
+    int record_type;
+    char* key;
+    char* value;
+}cal_extended_s;
+
+/**
+ * @}
+ */
+
+#endif // __CALENDAR_SVC_TYPEDEF_H__
diff --git a/common/cal_vcalendar.c b/common/cal_vcalendar.c
new file mode 100644 (file)
index 0000000..ba31633
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "calendar_vcalendar.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_record.h"
+#include "cal_view.h"
+#include "cal_time.h"
+#include "cal_list.h"
+
+#include "cal_vcalendar.h"
+#include "cal_vcalendar_make.h"
+#include "cal_vcalendar_parse.h"
+
+#define ICALENAR_BUFFER_MAX (1024*1024)
+
+API int calendar_vcalendar_make_from_records(calendar_list_h list, char **vcalendar_stream)
+{
+       int ret;
+       cal_make_s *b;
+       char *ical;
+
+       retvm_if(list == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: calendar_list_h is NULL");
+       retvm_if(vcalendar_stream == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: vcalendar_stream is NULL");
+
+       b = _cal_vcalendar_make_new();
+       retvm_if(!b, CALENDAR_ERROR_OUT_OF_MEMORY,
+                        "_cal_vcalendar_make_new() Failed");
+
+       ret = _cal_vcalendar_make_vcalendar(b, list);
+
+       if (ret < 0) {
+               _cal_vcalendar_make_free(&b);
+               return ret;
+       }
+
+       ical = _cal_vcalendar_make_get_data(b);
+       _cal_vcalendar_make_free(&b);
+
+       if (!ical) {
+               ERR("Failed to get ical data");
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       if (!*ical) {
+               ERR("No ical data");
+               return CALENDAR_ERROR_NO_DATA;
+       }
+
+       *vcalendar_stream = ical;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+/*
+ * parse from here
+ */
+
+API int calendar_vcalendar_parse_to_calendar(const char* vcalendar_stream, calendar_list_h *out_list)
+{
+       char *prop, *cont;
+       char *stream = NULL;
+       char *cursor = NULL;
+       calendar_list_h list = NULL;
+
+       retvm_if(vcalendar_stream == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: vcalendar_stream is NULL");
+       retvm_if(out_list == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: calendar_list_h * is NULL");
+
+       stream  = strdup(vcalendar_stream);
+       cursor = stream;
+
+       cursor = _cal_vcalendar_parse_remove_space(cursor);
+       if (cursor == NULL) {
+               ERR("_cal_vcalendar_parse_remove_space() failed");
+               CAL_FREE(stream);
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+       _cal_vcalendar_parse_unfolding(cursor);
+
+       cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont);
+       if (cursor == NULL) {
+               ERR("_cal_vcalendar_parse_read_line() failed");
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+               CAL_FREE(stream);
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       if (strncmp(prop, "BEGIN", strlen("BEGIN")) ||
+                       strncmp(cont + 1, "VCALENDAR", strlen("VCALENDAR"))) {
+               ERR("Failed to find BEGIN:VCALDENDAR [%s][%s]", prop, cont);
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+               return -1;
+       }
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       _cal_vcalendar_parse_vcalendar(&list, cursor);
+       if (list == NULL) {
+               ERR("No schedules");
+               CAL_FREE(stream);
+               return CALENDAR_ERROR_NO_DATA;
+       }
+
+       calendar_list_first(list);
+       *out_list = list;
+
+       CAL_FREE(stream);
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_vcalendar_parse_to_calendar_foreach(const char *vcalendar_file_path, calendar_vcalendar_parse_cb callback, void *user_data)
+{
+    FILE *file;
+       int ret = CALENDAR_ERROR_NONE;
+    int buf_size, len;
+    char *stream;
+    char buf[1024];
+
+    retvm_if(vcalendar_file_path == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid argument: vcalendar_file_path is NULL");
+    retvm_if(callback == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid argument: callback is NULL");
+
+    file = fopen(vcalendar_file_path, "r");
+
+    retvm_if(file == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid argument: no file");
+
+    len = 0;
+    buf_size = ICALENAR_BUFFER_MAX;
+    stream = malloc(ICALENAR_BUFFER_MAX);
+
+    while (fgets(buf, sizeof(buf), file))
+    {
+        if (len + sizeof(buf) < buf_size)
+        {
+            len += snprintf(stream + len, strlen(buf) +1, "%s", buf);
+        }
+        else
+        {
+            char *new_stream;
+            buf_size *= 2;
+            new_stream = realloc(stream, buf_size);
+            if (new_stream)
+            {
+                stream = new_stream;
+            } else
+            {
+                if (stream) free(stream);
+                fclose(file);
+                ERR("out of memory");
+                return CALENDAR_ERROR_OUT_OF_MEMORY;
+            }
+            len += snprintf(stream + len, strlen(buf) +1, "%s", buf);
+        }
+
+        if (!strncmp(buf, "END:VCALENDAR", strlen("END:VCALENDAR")))
+        {
+            DBG("end vcalendar");
+            calendar_list_h list = NULL;
+            int count = 0, i = 0;
+
+            if (calendar_vcalendar_parse_to_calendar(stream, &list) != CALENDAR_ERROR_NONE)
+            {
+                ERR("calendar_vcalendar_parse_to_calendar fail");
+                if (stream) free(stream);
+                fclose(file);
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+
+            ret = calendar_list_get_count(list, &count);
+                       if (ret != CALENDAR_ERROR_NONE || count < 1)
+                       {
+                               ERR("calendar_list_get_count() failed");
+                               calendar_list_destroy(list, true);
+                               if (stream) free(stream);
+                               fclose(file);
+                               return ret;
+                       }
+
+                       DBG("vcalendar has count(%d)", count);
+            calendar_list_first(list);
+            for(i = 0; i < count; i++)
+            {
+                calendar_record_h record = NULL;
+                if (calendar_list_get_current_record_p(list,&record) != CALENDAR_ERROR_NONE)
+                {
+                    ERR("calendar_list_get_count fail");
+                    calendar_list_destroy(list, true);
+                    if (stream) free(stream);
+                    fclose(file);
+                    return CALENDAR_ERROR_INVALID_PARAMETER;
+                }
+                if (!callback(record, user_data))
+                {
+                    ERR("callback is false");
+                    calendar_list_destroy(list, true);
+                    if (stream) free(stream);
+                    fclose(file);
+                    return CALENDAR_ERROR_INVALID_PARAMETER;
+                }
+            }
+
+            calendar_list_destroy(list, true);
+            len = 0;
+        }
+    }
+    if (stream) free(stream);
+    fclose(file);
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/cal_vcalendar.h b/common/cal_vcalendar.h
new file mode 100644 (file)
index 0000000..018ffe2
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_VCALENDAR_H__
+#define __CALENDAR_SVC_VCALENDAR_H__
+
+#define _RECORD(i) _calendar_##i
+
+enum {
+       VCALENDAR_TYPE_VEVENT = 0x1,
+       VCALENDAR_TYPE_VTODO,
+};
+
+#endif // __CALENDAR_SVC_VCALENDAR_H__
diff --git a/common/cal_vcalendar_make.c b/common/cal_vcalendar_make.c
new file mode 100644 (file)
index 0000000..0143640
--- /dev/null
@@ -0,0 +1,1198 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "calendar_list.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_record.h"
+#include "cal_view.h"
+#include "cal_time.h"
+
+#include "cal_vcalendar.h"
+#include "cal_vcalendar_make.h"
+
+typedef enum
+{
+       EVENT_ATTENDEE_REQ_PARTICIPANT_ROLE=0,
+       EVENT_ATTENDEE_OPT_PARTICIPANT_ROLE,
+       EVENT_ATTENDEE_NON_PARTICIPANT_ROLE,
+       EVENT_ATTENDEE_CHAIR_ROLE,
+} cal_event_attendee_role_type_t;
+
+typedef enum
+{
+       EVENT_ATTENDEE_NEEDS_ACTION_AT_STATUS=0,
+       EVENT_ATTENDEE_ACCEPTED_AT_STATUS,
+       EVENT_ATTENDEE_DECLINED_AT_STATUS,
+       EVENT_ATTENDEE_TENTATIVE_AT_STATUS,
+       EVENT_ATTENDEE_DELEGATED_AT_STATUS,
+       EVENT_ATTENDEE_COMPLETED_AT_STATUS,
+       EVENT_ATTENDEE_IN_PROCESS_AT_STATUS
+} cal_event_attendee_status_type_t;
+
+
+static const char *_att_role[] = {
+       [EVENT_ATTENDEE_REQ_PARTICIPANT_ROLE] = "REQ-PARTICIPANT",
+       [EVENT_ATTENDEE_OPT_PARTICIPANT_ROLE] = "OPT-PARTICIPANT",
+       [EVENT_ATTENDEE_NON_PARTICIPANT_ROLE] = "NON-PARTICIPANT",
+       [EVENT_ATTENDEE_CHAIR_ROLE] = "CHAIR",
+};
+
+static const char *_att_st[] = {
+       [EVENT_ATTENDEE_NEEDS_ACTION_AT_STATUS] = "NEEDS-ACTION",
+       [EVENT_ATTENDEE_ACCEPTED_AT_STATUS] = "ACCEPTED",
+       [EVENT_ATTENDEE_DECLINED_AT_STATUS] = "DECLINED",
+       [EVENT_ATTENDEE_TENTATIVE_AT_STATUS] = "TENTATIVE",
+       [EVENT_ATTENDEE_DELEGATED_AT_STATUS] = "DELEGATED",
+       [EVENT_ATTENDEE_COMPLETED_AT_STATUS] = "COMPLETED",
+       [EVENT_ATTENDEE_IN_PROCESS_AT_STATUS] = "IN-PROCESS",
+};
+
+#define _strlen(s) (((s) && *(s)) ? strlen(s) : 0)
+
+static inline int __cal_vcalendar_make_alloc(cal_make_s *b, int n)
+{
+       b->data = realloc(b->data, b->size + n);
+
+       retvm_if(!b->data, CALENDAR_ERROR_OUT_OF_MEMORY,
+                       "Failed to realloc");
+       b->size += n;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+cal_make_s *_cal_vcalendar_make_new(void)
+{
+       cal_make_s *b;
+
+       b = calloc(1, sizeof(cal_make_s));
+       if (!b) {
+               return NULL;
+       }
+
+       b->data = calloc(1, sizeof(char));
+       if (!b->data) {
+               free(b);
+               return NULL;
+       }
+
+       *b->data = '\0';
+       b->size = 1;
+
+       return b;
+}
+
+static inline int __cal_vcalendar_make_folding(cal_make_s *b)
+{
+       int ret;
+       ret = __cal_vcalendar_make_alloc(b, _strlen(b->lbuf) + 3);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       strncat(b->data, b->lbuf, b->size - _strlen(b->data) - 1);
+       strncat(b->data, "\r\n ", b->size - _strlen(b->data) - 1);
+       *b->lbuf = '\0';
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_set_str(cal_make_s *b, const char *s)
+{
+       int remain_lbuf;
+       int remain_str;
+       int k;
+       int ret;
+
+       remain_lbuf = sizeof(b->lbuf) - _strlen(b->lbuf);
+       remain_str = _strlen(s);
+
+       k = 0;
+       while ( remain_lbuf - 1 < remain_str) {
+               strncat(b->lbuf, s + k, remain_lbuf - 1);
+               k += remain_lbuf - 1;
+               remain_str -= remain_lbuf - 1;
+               ret = __cal_vcalendar_make_folding(b);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+               remain_lbuf = sizeof(b->lbuf);
+       }
+
+       strncat(b->lbuf, s + k, remain_lbuf - 1);
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_flush(cal_make_s *b)
+{
+       int ret;
+       ret = __cal_vcalendar_make_alloc(b, _strlen(b->lbuf) + 2);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       strncat(b->data, b->lbuf, b->size - _strlen(b->data) - 1);
+       strncat(b->data, "\r\n", b->size - _strlen(b->data) - 1);
+       *b->lbuf = '\0';
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_make_printf(cal_make_s *b, const char *s1, const char *s2)
+{
+       int ret;
+
+       if (s1) {
+               ret = __cal_vcalendar_make_set_str(b, s1);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       if (s2) {
+               ret = __cal_vcalendar_make_set_str(b, s2);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       return __cal_vcalendar_make_flush(b);
+}
+
+char *_cal_vcalendar_make_get_data(cal_make_s *b)
+{
+       if (!b || !b->data)
+               return NULL;
+       return strdup(b->data);
+}
+
+void _cal_vcalendar_make_free(cal_make_s **b)
+{
+       if (!b || !*b)
+               return;
+
+       if ((*b)->data)
+               free((*b)->data);
+
+       free(*b);
+       b = NULL;
+}
+
+static const char *__cal_vcalendar_make_itos(int y, int m, int d)
+{
+       static char buf[9];
+       snprintf(buf, sizeof(buf), "%04d%02d%02d", y, m, d);
+       return buf;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+static inline int __cal_vcalendar_make_class(cal_make_s *b, int v)
+{
+       const char *c;
+       // TODO : Need to define enumeration of class property
+       switch(v) {
+               case 0:
+                       c = "PUBLIC"; break;
+               case 1:
+                       c = "PRIVATE"; break;
+               case 2:
+                       c = "CONFIDENTIAL"; break;
+               default:
+                       c = "PUBLIC"; break;
+       }
+       __cal_vcalendar_make_printf(b, "CLASS:", c);
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_transp(cal_make_s *b, int v)
+{
+       // TODO : Need to define enumeration of transp property
+       __cal_vcalendar_make_printf(b, "TRANSP:", v? "OPAQUE":"TRANSPARENT");
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_created(cal_make_s *b, long long int t)
+{
+    char* tmp_tzid = NULL;
+    tmp_tzid = _cal_time_convert_ltos(NULL, t);
+    if (tmp_tzid)
+    {
+        __cal_vcalendar_make_printf(b, "CREATED:", tmp_tzid);
+        CAL_FREE(tmp_tzid);
+    }
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_description(cal_make_s *b, char *s)
+{
+       __cal_vcalendar_make_printf(b, "DESCRIPTION:", s);
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_dtstart(cal_make_s *b, calendar_time_s *caltime)
+{
+       retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
+
+       if (caltime->time.utime == CALENDAR_TODO_NO_START_DATE)
+       {
+               DBG("No start date");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       switch (caltime->type)
+       {
+       case CALENDAR_TIME_UTIME:
+        {
+            char* tmp_tzid = NULL;
+            tmp_tzid = _cal_time_convert_ltos(NULL, caltime->time.utime);
+            if (tmp_tzid)
+            {
+                __cal_vcalendar_make_printf(b, "DTSTART:", tmp_tzid);
+                CAL_FREE(tmp_tzid);
+            }
+        }
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               __cal_vcalendar_make_printf(b, "DTSTART:",
+                               __cal_vcalendar_make_itos(caltime->time.date.year,
+                                       caltime->time.date.month, caltime->time.date.mday));
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_last_mod(cal_make_s *b, long long int lli)
+{
+    char* tmp_tzid = NULL;
+    tmp_tzid = _cal_time_convert_ltos(NULL, lli);
+    if (tmp_tzid)
+    {
+        __cal_vcalendar_make_printf(b, "LAST-MODIFIED:",tmp_tzid);
+        CAL_FREE(tmp_tzid);
+    }
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_location(cal_make_s *b, char *s)
+{
+       __cal_vcalendar_make_printf(b, "LOCATION:", s);
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_organizer(cal_make_s *b, char *cn, char *address)
+{
+       int ret;
+
+       ret = __cal_vcalendar_make_set_str(b, "ORGANIZER");
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       if (cn && *cn)
+       {
+               ret = __cal_vcalendar_make_set_str(b, ";CN=");
+               ret = __cal_vcalendar_make_set_str(b, cn);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       if (address && *address)
+       {
+               ret = __cal_vcalendar_make_set_str(b, ":mailto:");
+               ret = __cal_vcalendar_make_set_str(b, address);
+       }
+       __cal_vcalendar_make_flush(b);
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_priority(cal_make_s *b, int v)
+{
+       char tmp[2];
+       snprintf(tmp, sizeof(tmp), "%d", v);
+       __cal_vcalendar_make_printf(b, "PRIORITY:", tmp);
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_dtstamp(cal_make_s *b, char *tzid)
+{
+    char* tmp_tzid = NULL;
+    tmp_tzid = _cal_time_convert_ltos(tzid, _cal_time_get_now());
+    if (tmp_tzid)
+    {
+        __cal_vcalendar_make_printf(b, "DTSTAMP:", tmp_tzid);
+        CAL_FREE(tmp_tzid);
+    }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_summary(cal_make_s *b, char *s)
+{
+       __cal_vcalendar_make_printf(b, "SUMMARY:", s);
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_dtend(cal_make_s *b, calendar_time_s *caltime)
+{
+       retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
+
+       if (caltime->time.utime == CALENDAR_TODO_NO_DUE_DATE)
+       {
+               DBG("No start date");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       switch (caltime->type)
+       {
+       case CALENDAR_TIME_UTIME:
+        {
+            char *tmp_tzid = NULL;
+            tmp_tzid = _cal_time_convert_ltos(NULL, caltime->time.utime);
+            if (tmp_tzid)
+            {
+                __cal_vcalendar_make_printf(b, "DTEND:", tmp_tzid);
+                CAL_FREE(tmp_tzid);
+            }
+        }
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               __cal_vcalendar_make_printf(b, "DTEND:",
+                               __cal_vcalendar_make_itos(caltime->time.date.year,
+                                       caltime->time.date.month, caltime->time.date.mday));
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_due(cal_make_s *b, calendar_time_s *caltime)
+{
+       retvm_if(caltime == NULL, -1, "Invalid argument: calendar_time_s is NULL");
+
+       switch (caltime->type)
+       {
+       case CALENDAR_TIME_UTIME:
+        {
+            char *tmp_tzid = NULL;
+            tmp_tzid = _cal_time_convert_ltos(NULL, caltime->time.utime);
+            if (tmp_tzid)
+            {
+                __cal_vcalendar_make_printf(b, "DUE:", tmp_tzid);
+                CAL_FREE(tmp_tzid);
+            }
+        }
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               __cal_vcalendar_make_printf(b, "DUE:",
+                               __cal_vcalendar_make_itos(caltime->time.date.year,
+                                       caltime->time.date.month, caltime->time.date.mday));
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int __cal_vcalendar_make_exdate(cal_make_s *b, char *s)
+{
+       __cal_vcalendar_make_printf(b, "EXDATE:", s);
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_attendee(cal_make_s *b, calendar_record_h attendee)
+{
+       int ret;
+       int role, status, rsvp;
+       char *group = NULL;
+       char *delegate_uri = NULL;
+       char *delegator_uri = NULL;
+       char *name = NULL;
+       char *email = NULL;
+
+       retvm_if(attendee == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: attendee is NULL");
+
+       ret = __cal_vcalendar_make_set_str(b, "ATTENDEE");
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       ret = calendar_record_get_str_p(attendee, _calendar_attendee.group, &group);
+
+       if (group && *group) {
+               ret = __cal_vcalendar_make_set_str(b, ";CUTYPE=");
+               ret = __cal_vcalendar_make_set_str(b, group);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       // TODO : NO 'member' member in cal_participant_info_t
+
+       ret = calendar_record_get_int(attendee, _calendar_attendee.role, &role);
+       {
+               ret = __cal_vcalendar_make_set_str(b, ";ROLE=");
+               ret = __cal_vcalendar_make_set_str(b, _att_role[role]);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       ret = calendar_record_get_int(attendee, _calendar_attendee.status, &status);
+       {
+               ret = __cal_vcalendar_make_set_str(b, ";PARTSTAT=");
+               ret = __cal_vcalendar_make_set_str(b, _att_st[status]);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       ret = calendar_record_get_int(attendee, _calendar_attendee.rsvp, &rsvp);
+       {
+               ret = __cal_vcalendar_make_set_str(b, ";RSVP=");
+               ret = __cal_vcalendar_make_set_str(b, rsvp ? "TRUE" : "FALSE");
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       ret = calendar_record_get_str_p(attendee,       _calendar_attendee.delegate_uri, &delegate_uri);
+       if (delegate_uri && *delegate_uri)
+       {
+               ret = __cal_vcalendar_make_set_str(b, ";DELEGATED-TO=");
+               ret = __cal_vcalendar_make_set_str(b, delegate_uri);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       ret = calendar_record_get_str_p(attendee, _calendar_attendee.delegator_uri, &delegator_uri);
+       if (delegator_uri && *delegator_uri)
+       {
+               ret = __cal_vcalendar_make_set_str(b, ";DELEGATED-FROM=");
+               ret = __cal_vcalendar_make_set_str(b, delegator_uri);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       // TODO : No 'sentby' member in cal_participant_info_t
+
+       ret = calendar_record_get_str_p(attendee, _calendar_attendee.name, &name);
+       if (name && *name) {
+               ret = __cal_vcalendar_make_set_str(b, ";CN=");
+               ret = __cal_vcalendar_make_set_str(b, name);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       ret = calendar_record_get_str_p(attendee,       _calendar_attendee.email, &email);
+       if (email && *email)
+       {
+               ret = __cal_vcalendar_make_set_str(b, ":mailto:");
+               ret = __cal_vcalendar_make_set_str(b, email);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+       __cal_vcalendar_make_flush(b);
+       return CALENDAR_ERROR_NONE;
+}
+
+static const char *vl_dur(calendar_alarm_time_unit_type_e unit, int dur)
+{
+       static char buf[8];
+       int i = 0;
+       char d[5];
+
+       if (dur < 0) {
+               *buf = '-';
+               i++;
+               dur = -dur;
+       }
+
+       snprintf(d, sizeof(d), "%d", dur);
+
+       *(buf + i) = 'P';
+       i++;
+
+       switch (unit) {
+               case CALENDAR_ALARM_TIME_UNIT_WEEK:
+                       snprintf(buf + i, sizeof(buf) - i, "%sW", d);
+                       break;
+               case CALENDAR_ALARM_TIME_UNIT_DAY:
+                       snprintf(buf + i, sizeof(buf) - i, "%sD", d);
+                       break;
+               case CALENDAR_ALARM_TIME_UNIT_HOUR:
+                       snprintf(buf + i, sizeof(buf) - i, "T%sH", d);
+                       break;
+               case CALENDAR_ALARM_TIME_UNIT_MINUTE:
+                       snprintf(buf + i, sizeof(buf) - i, "T%sM", d);
+                       break;
+               default:
+                       buf[0] = '\0';
+       }
+
+       return buf;
+}
+
+int __cal_vcalendar_make_trigger(cal_make_s *b, int unit, int dur, long long int t)
+{
+       retvm_if(unit < 0, CALENDAR_ERROR_NO_DATA, "tick unit is invalid");
+
+       if (unit == CALENDAR_ALARM_TIME_UNIT_SPECIFIC)
+       {
+           char* tmp_tzid = NULL;
+           tmp_tzid = _cal_time_convert_ltos(NULL, t);
+           if (tmp_tzid)
+           {
+               __cal_vcalendar_make_printf(b, "TRIGGER;VALUE=DATE-TIME:",tmp_tzid);
+               CAL_FREE(tmp_tzid);
+           }
+
+       }
+       else
+       {
+               __cal_vcalendar_make_printf(b, "TRIGGER:", vl_dur(unit, dur));
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_action(cal_make_s *b)
+{
+       return __cal_vcalendar_make_printf(b, "ACTION:", "AUDIO");
+}
+
+int __cal_vcalendar_make_audio(cal_make_s *b, calendar_record_h alarm)
+{
+       int ret;
+       int tick, unit;
+       long long int utime;
+
+       ret = __cal_vcalendar_make_action(b);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       ret = calendar_record_get_int(alarm, _calendar_alarm.tick, &tick);
+       ret = calendar_record_get_int(alarm, _calendar_alarm.tick_unit, &unit);
+       ret = calendar_record_get_lli(alarm, _calendar_alarm.time, &utime);
+
+       ret = __cal_vcalendar_make_trigger(b, unit, tick, utime);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // TODO : Support duration
+       // TODO : Support repeat (snooze)
+       return CALENDAR_ERROR_NONE;
+}
+
+int __cal_vcalendar_make_alarm(cal_make_s *b, calendar_record_h alarm)
+{
+       int ret;
+       retvm_if(alarm == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: alarm is NULL");
+
+       // TODO : No action type is defined
+       ret = __cal_vcalendar_make_printf(b, "BEGIN:VALARM", NULL);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       ret = __cal_vcalendar_make_audio(b, alarm);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // TODO : Display
+       // TODO : Email
+       // TODO : Proc
+
+       __cal_vcalendar_make_printf(b, "END:VALARM", NULL);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_make_rrule(cal_make_s *b, int freq, calendar_record_h record)
+{
+       int ret;
+       int num;
+       char *text = NULL;
+       char buf[1024] = {0};
+       char tmp[32] = {0};
+       calendar_time_s caltime = {0};
+
+       switch (freq) {
+       case CALENDAR_RECURRENCE_DAILY:
+               strcat(buf, "FREQ=DAILY");
+               break;
+       case CALENDAR_RECURRENCE_WEEKLY:
+               strcat(buf, "FREQ=WEEKLY");
+               break;
+       case CALENDAR_RECURRENCE_MONTHLY:
+               strcat(buf, "FREQ=MONTHLY");
+               break;
+       case CALENDAR_RECURRENCE_YEARLY:
+               strcat(buf, "FREQ=YEARLY");
+               break;
+       default:
+               break;
+       }
+
+       ret = calendar_record_get_int(record, _calendar_event.interval, &num);
+       snprintf(tmp, sizeof(tmp), "%d", num);
+       strcat(buf, ";INTERVAL=");
+       strcat(buf, tmp);
+
+       ret = calendar_record_get_str(record, _calendar_event.bysecond, &text);
+       if (text) {
+               strcat(buf, ";BYSECOND=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.byminute, &text);
+       if (text) {
+               strcat(buf, ";BYMINUTE=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.byhour, &text);
+       if (text) {
+               strcat(buf, ";BYHOUR=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.byday, &text);
+       if (text) {
+               strcat(buf, ";BYDAY=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.bymonthday, &text);
+       if (text) {
+               strcat(buf, ";BYMONTHDAY=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.byyearday, &text);
+       if (text) {
+               strcat(buf, ";BYYEARDAY=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.byweekno, &text);
+       if (text) {
+               strcat(buf, ";BYWEEKNO=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.bymonth, &text);
+       if (text) {
+               strcat(buf, ";BYMONTH=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       ret = calendar_record_get_str(record, _calendar_event.bysetpos, &text);
+       if (text) {
+               strcat(buf, ";BYSETPOS=");
+               strcat(buf, text);
+               CAL_FREE(text);
+               text = NULL;
+       }
+
+       num = CALENDAR_SUNDAY; // default set
+       ret = calendar_record_get_int(record, _calendar_event.wkst, &num);
+       strcat(buf, ";WKST=");
+       switch (num) {
+       case CALENDAR_SUNDAY:
+               strcat(buf, "SU");
+               break;
+       case CALENDAR_MONDAY:
+               strcat(buf, "MO");
+               break;
+       case CALENDAR_TUESDAY:
+               strcat(buf, "TU");
+               break;
+       case CALENDAR_WEDNESDAY:
+               strcat(buf, "WE");
+               break;
+       case CALENDAR_THURSDAY:
+               strcat(buf, "TH");
+               break;
+       case CALENDAR_FRIDAY:
+               strcat(buf, "FR");
+               break;
+       case CALENDAR_SATURDAY:
+               strcat(buf, "SA");
+               break;
+       }
+
+       ret = calendar_record_get_int(record, _calendar_event.range_type, &num);
+       switch (num) {
+       case CALENDAR_RANGE_COUNT:
+               ret = calendar_record_get_int(record, _calendar_event.count, &num);
+               snprintf(tmp, sizeof(tmp), "%d", num);
+               strcat(buf, ";COUNT=");
+               strcat(buf, tmp);
+               break;
+
+       case CALENDAR_RANGE_UNTIL:
+               ret = calendar_record_get_caltime(record, _calendar_event.until_time, &caltime);
+
+               if (caltime.type == CALENDAR_TIME_UTIME)
+               {
+                   char *tmp_tzid = NULL;
+                   tmp_tzid = _cal_time_convert_ltos(NULL, caltime.time.utime);
+                   if (tmp_tzid)
+                   {
+                       snprintf(tmp, sizeof(tmp), "%s", tmp_tzid);
+                       CAL_FREE(tmp_tzid);
+                   }
+               }
+               else
+               {
+                       snprintf(tmp, sizeof(tmp), "%04d%02d%02dT000000Z",
+                                       caltime.time.date.year,
+                                       caltime.time.date.month,
+                                       caltime.time.date.mday);
+               }
+               strcat(buf, ";UNTIL=");
+               strcat(buf, tmp);
+               break;
+
+       case CALENDAR_RANGE_NONE:
+               break;
+       default:
+               break;
+       }
+       return __cal_vcalendar_make_printf(b, "RRULE:", buf);
+}
+/////////////////////////////////////////////////////////////////////////////
+int __cal_vcalendar_make_schedule(cal_make_s *b, calendar_record_h record)
+{
+       int ret;
+       int freq;
+       int intval;
+       long long int llival;
+       char *strval = NULL;
+       char *strval2 = NULL;
+       calendar_time_s caltime = {0};
+       char *uri = NULL;
+       char *tzid = NULL;
+
+       ret = calendar_record_get_uri_p(record, &uri);
+
+       //_cal_db_rrule_fill_record(record);
+
+       ret = __cal_vcalendar_make_printf(b, "BEGIN:VEVENT", NULL);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // sensitivity
+       ret = calendar_record_get_int(record, _calendar_event.sensitivity, &intval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get sensitivity(%d)", ret);
+
+       __cal_vcalendar_make_class(b, intval);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // busy_status
+       ret = calendar_record_get_int(record, _calendar_event.busy_status, &intval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get busy_status(%d)", ret);
+
+       ret = __cal_vcalendar_make_transp(b, intval);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // created_time
+       ret = calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
+       ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
+       if (ret != CALENDAR_ERROR_NONE) {
+               ERR("Failed to get start_time(%d)", ret);
+               return -1;
+       }
+
+       ret = calendar_record_get_lli(record, _calendar_event.created_time, &llival);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get created_time(%d)", ret);
+
+       ret = __cal_vcalendar_make_created(b, llival);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+
+       // description
+       strval = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_event.description, &strval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get description(%d)", ret);
+
+       if (strval) {
+               ret = __cal_vcalendar_make_description(b, strval);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       } else {
+               DBG("No description");
+       }
+
+       // dtstart_type
+       ret = __cal_vcalendar_make_dtstart(b, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get dtstart(%d)", ret);
+
+       // TODO : geo
+
+       ret = calendar_record_get_int(record, _calendar_event.freq, &freq);
+       DBG("freq(%d)", freq);
+       if (freq)
+       {
+               __cal_vcalendar_make_rrule(b, freq, record);
+       }
+
+       // last_mod
+       ret = calendar_record_get_lli(record, _calendar_event.last_modified_time, &llival);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get last_modified_time(%d)", ret);
+
+       ret = __cal_vcalendar_make_last_mod(b, llival);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // location
+       strval = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_event.location, &strval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get location(%d)", ret);
+
+       if (strval) {
+               ret = __cal_vcalendar_make_location(b, strval);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       } else {
+               DBG("No location");
+       }
+
+       // organizer email
+       strval = NULL;
+       strval2 = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_event.organizer_name, &strval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get organizer_name(%d)", ret);
+
+       ret = calendar_record_get_str_p(record, _calendar_event.organizer_email, &strval2);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get organizer_email(%d)", ret);
+
+       if (strval || strval2) {
+               ret = __cal_vcalendar_make_organizer(b, strval, strval2);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       } else {
+               DBG("No organizer name or email");
+       }
+
+       // priority
+       ret = calendar_record_get_int(record, _calendar_event.priority, &intval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get priority(%d)", ret);
+
+       DBG("priority(%d)", intval);
+       ret = __cal_vcalendar_make_priority(b, intval);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // TODO : seq
+
+       // dtstamp
+       ret = __cal_vcalendar_make_dtstamp(b, tzid);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // summary
+       strval = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_event.summary, &strval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get summary(%d)", ret);
+
+       if (strval) {
+               ret = __cal_vcalendar_make_summary(b, strval);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       } else {
+               DBG("No summary");
+       }
+
+       // dtend
+       ret = calendar_record_get_caltime(record, _calendar_event.end_time, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get end_time(%d)", ret);
+
+       ret = __cal_vcalendar_make_dtend(b, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get dtstart(%d)", ret);
+
+       // exdate
+       strval = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_event.exdate, &strval);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_get_str_p() failed(ret:%d): exdate", ret);
+               return ret;
+       }
+       if (strval)
+       {
+               ret = __cal_vcalendar_make_exdate(b, strval);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("__cal_vcalendar_make_exdate() failed(ret:%d)", ret);
+                       return ret;
+               }
+       }
+
+       // attendee
+       unsigned int count;
+       calendar_record_h child = NULL;
+
+       ret = calendar_record_get_child_record_count(record,
+                       _calendar_event.calendar_attendee, &count);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get child count(%d)", ret);
+
+       while (count > 0)
+       {
+               count--;
+               ret = calendar_record_get_child_record_at_p(record,
+                               _calendar_event.calendar_attendee, count, &child);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                               "Failed to get child attendee(%d)", ret);
+
+               ret = __cal_vcalendar_make_attendee(b, child);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+       if (count <= 0)
+       {
+               DBG("No attendee");
+       }
+
+       // alarm
+       ret = calendar_record_get_child_record_count(record,
+                       _calendar_event.calendar_alarm, &count);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get child count(%d)", ret);
+
+       while (count > 0)
+       {
+               count--;
+               ret = calendar_record_get_child_record_at_p(record,
+                               _calendar_event.calendar_alarm, count, &child);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                               "Failed to get child alarm(%d)", ret);
+
+               ret = __cal_vcalendar_make_alarm(b, child);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       if (count <= 0)
+       {
+               DBG("No alarm");
+       }
+
+       return __cal_vcalendar_make_printf(b, "END:VEVENT", NULL);
+}
+
+int __cal_vcalendar_make_todo(cal_make_s *b, calendar_record_h record)
+{
+       int ret;
+       int intval;
+       long long int llival;
+       char *strval = NULL;
+       calendar_time_s caltime = {0};
+       char *uri = NULL;
+       char *tzid = NULL;
+
+       ret = calendar_record_get_uri_p(record, &uri);
+
+       //_cal_db_rrule_fill_record(record);
+
+       ret = __cal_vcalendar_make_printf(b, "BEGIN:VTODO", NULL);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // sensitivity
+       ret = calendar_record_get_int(record, _calendar_todo.sensitivity, &intval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get sensitivity(%d)", ret);
+
+       __cal_vcalendar_make_class(b, intval);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // created_time
+       ret = calendar_record_get_str_p(record, _calendar_todo.start_tzid, &tzid);
+       ret = calendar_record_get_caltime(record, _calendar_todo.start_time, &caltime);
+       if (ret != CALENDAR_ERROR_NONE) {
+               ERR("Failed to get start_time(%d)", ret);
+               return -1;
+       }
+
+       ret = calendar_record_get_lli(record, _calendar_todo.created_time, &llival);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get created_time(%d)", ret);
+
+       ret = __cal_vcalendar_make_created(b, llival);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+
+       // description
+       strval = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_todo.description, &strval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get description(%d)", ret);
+
+       if (strval) {
+               ret = __cal_vcalendar_make_description(b, strval);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       } else {
+               DBG("No description");
+       }
+
+       // dtstart_type
+       ret = __cal_vcalendar_make_dtstart(b, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get dtstart(%d)", ret);
+
+       // TODO : geo
+
+       // last_mod
+       ret = calendar_record_get_lli(record, _calendar_todo.last_modified_time, &llival);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get last_modified_time(%d)", ret);
+
+       ret = __cal_vcalendar_make_last_mod(b, llival);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // location
+       strval = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_todo.location, &strval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get location(%d)", ret);
+
+       if (strval) {
+               ret = __cal_vcalendar_make_location(b, strval);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       } else {
+               DBG("No location");
+       }
+
+       // priority
+       ret = calendar_record_get_int(record, _calendar_todo.priority, &intval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get priority(%d)", ret);
+
+       DBG("priority(%d)", intval);
+       ret = __cal_vcalendar_make_priority(b, intval);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // TODO : seq
+
+       // dtstamp
+       ret = __cal_vcalendar_make_dtstamp(b, tzid);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       // summary
+       strval = NULL;
+       ret = calendar_record_get_str_p(record, _calendar_todo.summary, &strval);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get summary(%d)", ret);
+
+       if (strval) {
+               ret = __cal_vcalendar_make_summary(b, strval);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       } else {
+               DBG("No summary");
+       }
+
+       // dtend
+       ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get due_time(%d)", ret);
+
+       ret = __cal_vcalendar_make_due(b, &caltime);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "__cal_vcalendar_make_due() failed(%d)", ret);
+
+       // alarm
+       unsigned int count;
+       calendar_record_h child = NULL;
+       ret = calendar_record_get_child_record_count(record,
+                       _calendar_todo.calendar_alarm, &count);
+       retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                       "Failed to get child count(%d)", ret);
+
+       while (count > 0)
+       {
+               count--;
+               ret = calendar_record_get_child_record_at_p(record,
+                               _calendar_todo.calendar_alarm, count, &child);
+               retvm_if(ret != CALENDAR_ERROR_NONE, -1,
+                               "Failed to get child alarm(%d)", ret);
+
+               ret = __cal_vcalendar_make_alarm(b, child);
+               retv_if(ret != CALENDAR_ERROR_NONE, ret);
+       }
+
+       if (count <= 0)
+       {
+               DBG("No alarm");
+       }
+
+       return __cal_vcalendar_make_printf(b, "END:VTODO", NULL);
+}
+
+int _cal_vcalendar_make_vcalendar(cal_make_s *b, calendar_list_h list)
+{
+       int ret;
+       char *uri = NULL;
+       calendar_record_h record;
+
+       ret = __cal_vcalendar_make_printf(b, "BEGIN:VCALENDAR", NULL);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       ret = __cal_vcalendar_make_printf(b, "CALSCALE:GREGORIAN", NULL);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       ret = __cal_vcalendar_make_printf(b, "PRODID:-//Samsung Electronics//Calendar//EN", NULL);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       ret = __cal_vcalendar_make_printf(b, "VERSION:2.0", NULL);
+       retv_if(ret != CALENDAR_ERROR_NONE, ret);
+
+       ret = calendar_list_first(list);
+       retvm_if(ret != CALENDAR_ERROR_NONE, ret,
+                       "calendar_list_first() Failed");
+
+       do
+       {
+               ret = calendar_list_get_current_record_p(list, &record);
+               if (ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("Failed to get current record(%d)", ret);
+                       break;
+               }
+               ret = calendar_record_get_uri_p(record, &uri);
+               if (!strcmp(uri, CALENDAR_VIEW_EVENT))
+               {
+                       ret = __cal_vcalendar_make_schedule(b, record);
+
+               }
+               else if (!strcmp(uri, CALENDAR_VIEW_TODO))
+               {
+                       ret = __cal_vcalendar_make_todo(b, record);
+
+               }
+
+               if (ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("__cal_vcalendar_make_schedule() Failed(%d)", ret);
+                       break;
+               }
+       } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+       __cal_vcalendar_make_printf(b, "END:VCALENDAR", NULL);
+
+       return CALENDAR_ERROR_NONE;
+}
+
diff --git a/common/cal_vcalendar_make.h b/common/cal_vcalendar_make.h
new file mode 100644 (file)
index 0000000..1a1ccb4
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_VCALENDAR_MAKE_H__
+#define __CALENDAR_SVC_VCALENDAR_MAKE_H__
+
+#include "calendar_vcalendar.h"
+
+typedef struct {
+       int size;
+       char *data;
+       char lbuf[76];
+} cal_make_s ;
+
+cal_make_s *_cal_vcalendar_make_new(void);
+int _cal_vcalendar_make_vcalendar(cal_make_s *b, calendar_list_h list);
+char *_cal_vcalendar_make_get_data(cal_make_s *b);
+void _cal_vcalendar_make_free(cal_make_s **b);
+
+#endif // __CALENDAR_SVC_VCALENDAR_MAKE_H__
diff --git a/common/cal_vcalendar_parse.c b/common/cal_vcalendar_parse.c
new file mode 100644 (file)
index 0000000..53113cc
--- /dev/null
@@ -0,0 +1,3040 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <ctype.h>
+
+#include "calendar_list.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_record.h"
+#include "cal_view.h"
+#include "cal_time.h"
+
+#include "cal_vcalendar.h"
+#include "cal_vcalendar_parse.h"
+
+enum {
+       ENCODE_NONE = 0x0,
+       ENCODE_BASE64,
+       ENCODE_QUOTED_PRINTABLE,
+       ENCODE_MAX,
+};
+
+struct _prop_func {
+       char *prop;
+       int (*func)(int *val, void *data);
+};
+
+struct _vcalendar_func {
+       char *prop;
+       int (*func)(int ver, calendar_list_h list, calendar_record_h event, void *data);
+};
+
+struct _record_func {
+       char *prop;
+       int (*func)(calendar_record_h record, void *data);
+};
+
+char *_cal_vcalendar_parse_vcalendar(calendar_list_h *list_sch, void *data);
+char *_cal_vcalendar_parse_vevent(int ver, calendar_list_h *list_sch, void *data);
+char *_cal_vcalendar_parse_vtodo(int ver, calendar_list_h *list_sch, void *data);
+char *_cal_vcalendar_parse_valarm(int type, calendar_record_h record, void *data);
+
+enum {
+       VCAL_PRODID = 0x0,
+       VCAL_VERSION,
+//     VCAL_CALSCALE,
+//     VCAL_METHOD,
+       VCAL_MAX,
+};
+
+static int __cal_vcalendar_parse_prodid(int *val, void *data);
+static int __cal_vcalendar_parse_version(int *val, void *data);
+
+struct _prop_func _basic_funcs[VCAL_MAX] =
+{
+       {"PRODID", __cal_vcalendar_parse_prodid },
+       {"VERSION", __cal_vcalendar_parse_version }//,
+//     {"CALSCALE", __cal_vcalendar_parse_calscale },
+//     {"METHOD", __cal_vcalendar_parse_method }
+};
+
+static int __cal_vcalendar_parse_dtstamp(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_uid(int type, calendar_list_h list, calendar_record_h record, void *data);
+static int __cal_vcalendar_parse_dtstart(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_created(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_description(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_last_mod(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_location(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_priority(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_status(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_summary(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_rrule(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_dtend(int ver, calendar_list_h list, calendar_record_h event, void *data);
+
+static int __cal_vcalendar_parse_completed(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_percent(int ver, calendar_list_h list, calendar_record_h event, void *data);
+
+enum {
+       ATTENDEE_CUTYPE = 0x0,
+       ATTENDEE_MEMBER,
+       ATTENDEE_ROLE,
+       ATTENDEE_PARTSTAT,
+       ATTENDEE_RSVP,
+       ATTENDEE_DELTO,
+       ATTENDEE_DELFROM,
+       ATTENDEE_SENTBY,
+       ATTENDEE_CN,
+       ATTENDEE_DIR,
+       ATTENDEE_MAX,
+};
+
+static int __cal_vcalendar_parse_attendee_cutype(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_member(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_role(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_partstat(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_rsvp(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_delto(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_delfrom(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_sentby(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_cn(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_attendee_dir(calendar_record_h event, void *data);
+
+struct _record_func _attendee_funcs[ATTENDEE_MAX] =
+{
+       { "CUTYPE=", __cal_vcalendar_parse_attendee_cutype },
+       { "MEMBER=", __cal_vcalendar_parse_attendee_member },
+       { "ROLE=", __cal_vcalendar_parse_attendee_role },
+       { "PARTSTAT=", __cal_vcalendar_parse_attendee_partstat },
+       { "RSVP=", __cal_vcalendar_parse_attendee_rsvp },
+       { "DELTO=", __cal_vcalendar_parse_attendee_delto },
+       { "DELFROM=", __cal_vcalendar_parse_attendee_delfrom },
+       { "SENTBY=", __cal_vcalendar_parse_attendee_sentby },
+       { "CN=", __cal_vcalendar_parse_attendee_cn },
+       { "DIR=", __cal_vcalendar_parse_attendee_dir }
+};
+
+static int __cal_vcalendar_parse_attendee(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_categories(int ver, calendar_list_h list, calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_aalarm(int ver, calendar_list_h list, calendar_record_h event, void *data);
+
+enum {
+       VEVE_DTSTAMP = 0x0,
+       VEVE_UID,
+       VEVE_DTSTART,
+       VEVE_CREATED,
+       VEVE_DESCRIPTION,
+       VEVE_LAST_MOD,
+       VEVE_LOCATION,
+       VEVE_PRIORITY,
+       VEVE_STATUS,
+       VEVE_SUMMARY,
+       VEVE_RRULE,
+       VEVE_DTEND,
+       VEVE_DUE,
+       VEVE_ATTENDEE,
+       VEVE_CATEGORIES,
+       VEVE_AALARM,    /* for ver 1.0 */
+       VEVE_MAX,
+};
+
+struct _vcalendar_func _vevent_funcs[VEVE_MAX] =
+{
+       { "DTSTAMP", __cal_vcalendar_parse_dtstamp },
+       { "UID", __cal_vcalendar_parse_uid },
+       { "DTSTART", __cal_vcalendar_parse_dtstart },
+       { "CREATED", __cal_vcalendar_parse_created },
+       { "DESCRIPTION", __cal_vcalendar_parse_description },
+       { "LAST-MOD", __cal_vcalendar_parse_last_mod },
+       { "LOCATION", __cal_vcalendar_parse_location },
+       { "PRIORITY", __cal_vcalendar_parse_priority },
+       { "STATUS", __cal_vcalendar_parse_status },
+       { "SUMMARY", __cal_vcalendar_parse_summary },
+       { "RRULE", __cal_vcalendar_parse_rrule },
+       { "DTEND", __cal_vcalendar_parse_dtend },
+       { "DUE", __cal_vcalendar_parse_dtend },
+       { "ATTENDEE", __cal_vcalendar_parse_attendee },
+       { "CATEGORIES", __cal_vcalendar_parse_categories },
+       { "AALARM", __cal_vcalendar_parse_aalarm },
+};
+
+static int __cal_vcalendar_parse_action(calendar_record_h alarm, void *data);
+static int __cal_vcalendar_parse_trigger(calendar_record_h alarm, void *data);
+static int __cal_vcalendar_parse_repeat(calendar_record_h alarm, void *data);
+static int __cal_vcalendar_parse_duration_alarm(calendar_record_h alarm, void *data);
+static int __cal_vcalendar_parse_attach_alarm(calendar_record_h alarm, void *data);
+static int __cal_vcalendar_parse_summary_alarm(calendar_record_h alarm, void *data);
+
+enum {
+       VALA_ACTION = 0x0,
+       VALA_TRIGGER,
+       VALA_REPEAT,
+       VALA_DURATION,
+       VALA_ATTACH,
+//     VALA_DESCRIPTION,
+       VALA_SUMMARY,
+//     VALA_ATTENDEE,
+       VALA_MAX,
+};
+
+struct _record_func _valarm_funcs[VALA_MAX] =
+{
+       { "ACTION", __cal_vcalendar_parse_action },
+       { "TRIGGER", __cal_vcalendar_parse_trigger },
+       { "REPEAT", __cal_vcalendar_parse_repeat },
+       { "DURATION", __cal_vcalendar_parse_duration_alarm },
+       { "ATTACH", __cal_vcalendar_parse_attach_alarm },
+//     { "DESCRIPTION", __cal_vcalendar_parse_description },
+       { "SUMMARY", __cal_vcalendar_parse_summary_alarm },
+//     { "ATTENDEE", __cal_vcalendar_parse_attendee },
+};
+
+enum {
+       VTODO_DTSTAMP = 0x0,
+       VTODO_UID,
+//     VTODO_CLASS,
+       VTODO_COMPLETED,
+       VTODO_CREATED,
+       VTODO_DESCRIPTION,
+       VTODO_DTSTART,
+//     VTODO_GEO,
+       VTODO_LAST_MOD,
+       VTODO_LOCATION,
+//     VTODO_ORGANIZER,
+       VTODO_PERCENT,
+       VTODO_PRIORITY,
+//     VTODO_RECURID,
+//     VTODO_SEQ,
+       VTODO_STATUS,
+       VTODO_SUMMARY,
+//     VTODO_URL,
+//     VTODO_RRULE,
+       VTODO_DUE,
+//     VTODO_DURATION,
+//     VTODO_ATTACH,
+//     VTODO_ATTENDEE,
+//     VTODO_CATEGORIES,
+//     VTODO_COMMENT,
+//     VTODO_CONTACT,
+//     VTODO_EXDATE,
+//     VTODO_RSTATUS,
+//     VTODO_RELATED,
+//     VTODO_RESOURCES,
+//     VTODO_RDATE,
+//     VTODO_X_PROP,
+//     VTODO_IANA_PROP,
+       VTODO_AALARM,   /* for ver 1.0 */
+       VTODO_MAX,
+};
+
+struct _vcalendar_func _vtodo_funcs[VTODO_MAX] =
+{
+       { "DTSTAMP", __cal_vcalendar_parse_dtstamp },
+       { "UID", __cal_vcalendar_parse_uid },
+       { "COMPLETED", __cal_vcalendar_parse_completed },
+       { "CREATED", __cal_vcalendar_parse_created },
+       { "DESCRIPTION", __cal_vcalendar_parse_description },
+       { "DTSTART", __cal_vcalendar_parse_dtstart },
+       { "LAST-MOD", __cal_vcalendar_parse_last_mod },
+       { "LOCATION", __cal_vcalendar_parse_location },
+       { "PERCENT", __cal_vcalendar_parse_percent },
+       { "PRIORITY", __cal_vcalendar_parse_priority },
+       { "STATUS", __cal_vcalendar_parse_status },
+       { "SUMMARY", __cal_vcalendar_parse_summary },
+       { "DUE", __cal_vcalendar_parse_dtend },
+       { "AALARM", __cal_vcalendar_parse_aalarm },
+};
+
+static int __cal_vcalendar_parse_freq(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_until(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_count(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_interval(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_bysecond(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_byminute(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_byhour(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_byday(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_bymonthday(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_byyearday(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_byweekno(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_bymonth(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_bysetpos(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_wkst(calendar_record_h event, void *data);
+
+enum {
+       RRULE_FREQ = 0x0,
+       RRULE_UNTIL,
+       RRULE_COUNT,
+       RRULE_INTERVAL,
+       RRULE_BYSECOND,
+       RRULE_BYMINUTE,
+       RRULE_BYHOUR,
+       RRULE_BYDAY,
+       RRULE_BYMONTHDAY,
+       RRULE_BYYEARDAY,
+       RRULE_BYWEEKNO,
+       RRULE_BYMONTH,
+       RRULE_BYSETPOS,
+       RRULE_WKST,
+       RRULE_MAX,
+};
+
+struct _record_func _rrule_funcs[RRULE_MAX] =
+{
+       { "FREQ=", __cal_vcalendar_parse_freq },
+       { "UNTIL=", __cal_vcalendar_parse_until },
+       { "COUNT=", __cal_vcalendar_parse_count },
+       { "INTERVAL=", __cal_vcalendar_parse_interval },
+       { "BYSECOND=", __cal_vcalendar_parse_bysecond },
+       { "BYMINUTE=", __cal_vcalendar_parse_byminute },
+       { "BYHOUR=", __cal_vcalendar_parse_byhour },
+       { "BYDAY=", __cal_vcalendar_parse_byday },
+       { "BYMONTHDAY=", __cal_vcalendar_parse_bymonthday },
+       { "BYYEARDAY=", __cal_vcalendar_parse_byyearday },
+       { "BYWEEKNO=", __cal_vcalendar_parse_byweekno },
+       { "BYMONTH=", __cal_vcalendar_parse_bymonth },
+       { "BYSETPOS=", __cal_vcalendar_parse_bysetpos },
+       { "WKST=", __cal_vcalendar_parse_wkst }
+};
+
+static int __cal_vcalendar_parse_trig_related(calendar_record_h event, void *data);
+static int __cal_vcalendar_parse_trig_value(calendar_record_h event, void *data);
+
+enum {
+       TRIG_RELATED = 0x0,
+       TRIG_VALUE,
+       TRIG_MAX,
+};
+
+struct _record_func _trig_funcs[TRIG_MAX] =
+{
+       { "RELATED=", __cal_vcalendar_parse_trig_related },
+       { "VALUE=", __cal_vcalendar_parse_trig_value }
+};
+
+static int __cal_vcalendar_parse_charset(int *val, void *data);
+static int __cal_vcalendar_parse_encoding(int *val, void *data);
+
+
+enum {
+       TEXT_CHARSET = 0x0,
+       TEXT_ENCODING,
+       TEXT_MAX,
+};
+
+struct _prop_func _optional_funcs[TEXT_MAX] =
+{
+       { "CHARSET=", __cal_vcalendar_parse_charset },
+       { "ENCODING=", __cal_vcalendar_parse_encoding },
+};
+
+//util //////////////////////////////////////////////////////////////////////
+
+
+char *_cal_vcalendar_parse_remove_space(char *src)
+{
+       while (*src) {
+               if ('\n' != *src && '\r' != *src) {
+                       break;
+               }
+               src++;
+       }
+       return src;
+}
+
+static char __cal_vcalendar_parse_decode_hexa(char *p)
+{
+       int i;
+       char decoded[2] = {0x00, 0x00};
+
+       for (i = 0; i < 2; i++) {
+               switch (p[i]) {
+               case '0' ... '9':
+                       decoded[i] = p[i] - '0';
+                       break;
+               case 'a' ... 'f':
+                       decoded[i] = p[i] - 'a' + 10;
+                       break;
+               case 'A' ... 'F':
+                       decoded[i] = p[i] - 'A' + 10;
+                       break;
+               }
+       }
+
+       return (char)((decoded[0] << 4) + decoded[1]);
+}
+
+static int __cal_vcalendar_parse_decode_quoted_printable(char *p, int *len)
+{
+       int i = 0, j = 0;
+       char ch;
+
+       while (p[i]) {
+               if (p[i] == '=') {
+                       if (p[i+1] == 0x09 || p[i+1] == 0x20) {
+                               i +=3;
+
+                       } else if (p[i+1] == '\r' || p[i+1] == '\n') {
+                               i +=3;
+
+                       } else {
+                               if (p[i+1] == '0' && tolower(p[i+2]) == 'd' &&
+                                               p[i+3] == '=' && p[i+4] == '0' && tolower(p[i+5]) == 'a') {
+                                       p[j] = '\n';
+                                       j++;
+                                       i += 6;
+                               } else {
+                                       ch = __cal_vcalendar_parse_decode_hexa(&p[i+1]);
+                                       p[j] = ch;
+                                       j++;
+                                       i += 3;
+                               }
+                       }
+               } else {
+                       p[j] = p[i];
+                       j++;
+                       i++;
+               }
+       }
+       p[j] = '\0';
+       *len = i;
+       return CALENDAR_ERROR_NONE;
+}
+
+////////////////////////////////////////////////////////////////////////
+
+int _cal_vcalendar_parse_unfolding(char *stream)
+{
+       char *p;
+
+       retv_if(stream == NULL, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       p = stream;
+       while (*stream) {
+               if ('=' == *stream && '\r' == *(stream + 1) && '\n' == *(stream + 2))
+               {
+                       stream += 3;
+               }
+               else if ('\n' == *stream && ' ' == *(stream + 1))
+               {
+                       stream += 2;
+                       p--;
+               }
+               else if ('\0' == *stream)
+               {
+                       DBG("break\n");
+                       break;
+               }
+               *p = *stream;
+               p++;
+               stream++;
+
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+char *_cal_vcalendar_parse_read_line(char *stream, char **prop, char **cont)
+{
+       int i;
+       char *p, *q;
+       int out;
+
+       /* skip space */
+       p = stream;
+       q = p;
+       out = 0;
+       while (*p) {
+               switch (*p) {
+               case ' ':
+                       break;
+               default:
+                       out = 1;
+                       break;
+               }
+               if (out == 1) {
+                       break;
+               }
+               p++;
+       }
+
+       i = 0;
+       out = 0;
+       q = p;
+       while (*p) {
+               switch (*p) {
+               case ';':
+               case ':':
+                       out = 1;
+                       break;
+               default:
+                       i++;
+                       break;
+               }
+               if (out == 1) {
+                       i++;
+                       break;
+               }
+               p++;
+       }
+
+       if (0 < i) {
+               *prop = calloc(1, i);
+               snprintf(*prop, i, "%s", q);
+       } else {
+               *prop = NULL;
+               *cont = NULL;
+               return NULL;
+       }
+
+       i = 0;
+       out = 0;
+       q = p;
+
+       while (*p) {
+               switch (*p) {
+               case '\r':
+                       if ('\n' == *(p + 1)) {
+                               out = 1;
+                       }
+                       break;
+               case '\0':
+                       break;
+               default:
+                       i++;
+                       break;
+               }
+               if (out == 1) {
+                       i++;
+                       break;
+               }
+               p++;
+       }
+
+       if (0 < i) {
+               *cont = calloc(1, i);
+               snprintf(*cont, i, "%s", q);
+               p += 2;
+       } else {
+               *prop = NULL;
+               *cont = NULL;
+               return NULL;
+       }
+
+       DBG("%s][%s\n", *prop, *cont);
+       return p;
+}
+
+// start parse func ////////////////////////////////////////////////////
+/* vcalendar */////////////////////////////////////////////////
+
+static int __cal_vcalendar_parse_prodid(int *val, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_version(int *val, void *data)
+{
+       char *p = (char *)data;
+
+       p++;
+       if (!strncmp(p, "1.0", strlen("1.0")))
+       {
+               DBG("version 1.0");
+       }
+       else if (!strncmp(p, "2.0", strlen("2.0")))
+       {
+               DBG("version 2.0");
+       }
+       else
+       {
+               DBG("Invald version");
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+/* vevnt */////////////////////////////////////////////////
+static int __cal_vcalendar_parse_dtstamp(int ver, calendar_list_h list, calendar_record_h event, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_uid(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       char *p = (char *)data;
+
+       p++;
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_str(record, _calendar_event.uid, p);
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_str(record, _calendar_todo.uid, p);
+               break;
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_get_tzid_from_list(calendar_list_h list, const char *tzid, calendar_record_h *timezone)
+{
+       GList *l = NULL;
+
+       if (list == NULL || tzid == NULL)
+       {
+               return -1;
+       }
+
+       cal_list_s *cal_list = (cal_list_s *)list;
+       l = g_list_first(cal_list->record);
+
+       while (l)
+       {
+               char *uri = NULL;
+               calendar_record_h record = (calendar_record_h)l->data;
+               calendar_record_get_uri_p(record, &uri);
+               if (strncmp(uri, _calendar_timezone._uri, strlen(_calendar_timezone._uri)))
+               {
+                       l = g_list_next(l);
+                       continue;
+               }
+
+               cal_timezone_s *tz = (cal_timezone_s *)record;
+               if (!strncmp(tz->standard_name, tzid, strlen(tzid)))
+               {
+                       DBG("Found same tzid[%s] in the list", tzid);
+                       *timezone = record;
+                       break;
+               }
+
+               l = g_list_next(l);
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_dtstart(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       char *p = (char *)data;
+       int k = 0, j;
+       char *tzid = NULL; // free after appling
+       char buf[64] = {0, };
+       calendar_time_s start = {0};
+
+       p++;
+
+       int is_quot = 0;
+       if (!strncmp(p, "TZID=", strlen("TZID="))) {
+               k = 0;
+               j = strlen("TZID=");
+               while ((p[j] != ':' && p[j] != ';' && p[j] != '\n' && p[j] != '\0') || is_quot == 1) {
+                       if (p[j] == '\"' && is_quot == 0)
+                       {
+                               is_quot = 1;
+                               j++;
+                       }
+                       else if (p[j] == '\"' && is_quot == 1)
+                       {
+                               is_quot = 0;
+                               j++;
+                               break;
+                       }
+                       else
+                       {
+                       }
+
+                       buf[k] = p[j];
+                       k++;
+                       j++;
+               }
+               if (p[j] != '\0') {
+                       buf[k] = '\0';
+               }
+               p += j;
+               p++;
+       } else {
+               snprintf(buf, sizeof(buf), "%s", CAL_TZID_GMT);
+       }
+       tzid = strdup(buf);
+       DBG("tzid[%s]", tzid);
+       DBG("next[%s]", p);
+
+       if (!strncmp(p, "VALUE=", strlen("VALUE="))) {
+               k = 0;
+               j = strlen("VALUE=");
+               while (p[j] != ':' && p[j] != ';' && p[j] != '\n' && p[j] != '\0') {
+                       buf[k] = p[j];
+                       k++;
+                       j++;
+               }
+               if (p[j] != '\0') {
+                       buf[k] = '\0';
+               }
+               p += j;
+               p++;
+       }
+
+       int y, mon, d, h, min, s;
+       char t, z;
+
+       if (!strncmp(buf, "DATE", strlen("DATE"))){
+               DBG("value is date");
+               start.type = CALENDAR_TIME_LOCALTIME;
+
+               sscanf(p, "%4d%2d%2d", &y, &mon, &d);
+               start.time.date.year = y;
+               start.time.date.month = mon;
+               start.time.date.mday = d;
+
+       } else {
+               DBG("value is utime");
+               start.type = CALENDAR_TIME_UTIME;
+
+               sscanf(p, "%4d%2d%2d%c%2d%2d%2d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
+
+               if (strlen(p) != strlen("YYYYMMDDTHHMMSS"))
+               {
+                       start.time.utime = _cal_time_convert_itol(NULL, y, mon, d, h, min, s);
+               }
+               else
+               {
+                       char *like_tzid = NULL;
+                       if (_cal_time_is_registered_tzid(tzid))
+                       {
+                               start.time.utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+                       }
+                       else
+                       {
+                               calendar_record_h timezone = NULL;
+                               // try get timezone info from the list
+                               __cal_vcalendar_parse_get_tzid_from_list(list, tzid, &timezone);
+                               if (timezone)
+                               {
+                                       DBG("Found from the list");
+                                       _cal_time_get_like_tzid(tzid, timezone, &like_tzid);
+                                       start.time.utime = _cal_time_convert_itol(like_tzid, y, mon, d, h, min, s);
+                                       DBG("[%s]", like_tzid);
+                                       CAL_FREE(like_tzid);
+                                       like_tzid = NULL;
+                               }
+                               else
+                               {
+                                       DBG("Nowhere to find");
+                                       start.time.utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+                               }
+                       }
+               }
+       }
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_str(record, _calendar_event.start_tzid, tzid);
+               ret = _cal_record_set_caltime(record, _calendar_event.start_time, start);
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_str(record, _calendar_todo.start_tzid, tzid);
+               ret = _cal_record_set_caltime(record, _calendar_todo.start_time, start);
+               break;
+       }
+       if (tzid) free(tzid);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_created(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       char *p = (char *)data;
+
+       p++;
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_lli(record, _calendar_event.created_time,
+                               _cal_time_convert_stol(NULL, p));
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_lli(record, _calendar_todo.created_time,
+                               _cal_time_convert_stol(NULL, p));
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __work_description_switch(int me, int mode, char *buf, int *charset, int *encoding)
+{
+       switch (mode) {
+       case 1:
+       case 2:
+               if (!strncmp(buf, "CHARSET=UTF-8", strlen("CHARSET=UTF-8"))) {
+                       DBG("CHARSET=UTF-8");
+                       *charset = 1;
+
+               } else if (!strncmp(buf, "CHARSET=UTF-16",
+                                       strlen("CHARSET=UTF-16"))) {
+                       DBG("CHARSET=UTF-16");
+                       *charset = 1;
+
+               } else if (!strncmp(buf, "ENCODING=BASE64",
+                                       strlen("ENCODING=BASE64"))) {
+                       DBG("ENCODE_BASE64");
+                       *encoding = ENCODE_BASE64;
+
+               } else if (!strncmp(buf, "ENCODING=QUOTED-PRINTABLE",
+                                       strlen("ENCODING=QUOTED-PRINTABLE"))) {
+                       DBG("ENCODE_QUOTED_PRINTABLE");
+                       *encoding = ENCODE_QUOTED_PRINTABLE;
+
+               } else {
+
+               }
+               mode = 0;
+               break;
+       default:
+               mode = me;
+               break;
+       }
+       return mode;
+}
+
+static int __cal_vcalendar_parse_description(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int i, j;
+       int ret;
+       int len;
+       int out;
+       int mode;
+       int charset, encoding;
+       char buf[64] = {0};
+       char *p = (char *)data;
+
+       i = j = 0;
+       out = 0;
+       mode = 0;
+       charset = encoding = 0;
+       while (p[i] != '\0') {
+               switch (p[i]) {
+               case ':':
+                       mode = 1;
+                       out = 1;
+                       break;
+
+               case ';':
+                       buf[j] = '\0';
+                       mode = __work_description_switch(2, mode, buf, &charset, &encoding);
+                       j = 0;
+                       break;
+
+               default:
+                       buf[j] = p[i];
+                       j++;
+                       break;
+               }
+               i++;
+
+               if (out) {
+                       DBG("out");
+                       break;
+               }
+       }
+       __work_description_switch(0, mode, buf, &charset, &encoding);
+
+       DBG("charset(%d) encoding(%d)", charset, encoding);
+       if (encoding) {
+               __cal_vcalendar_parse_decode_quoted_printable(p+i, &len);
+       }
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_str(record, _calendar_event.description, p + i);
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_str(record, _calendar_todo.description, p + i);
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_last_mod(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       char *p = (char *)data;
+
+       p++;
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_lli(record, _calendar_event.last_modified_time,
+                               _cal_time_convert_stol(NULL, p));
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_lli(record, _calendar_todo.last_modified_time,
+                               _cal_time_convert_stol(NULL, p));
+               break;
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+inline void __cal_vcalendar_parse_get_optional(char *p, int *encoding)
+{
+       int i;
+
+       for (i = 0; i < TEXT_MAX; i++) {
+               if (!strncmp(p, _optional_funcs[i].prop, strlen(_optional_funcs[i].prop))) {
+                       int j = 0;
+                       char buf[64] = {0, };
+                       p += strlen(_optional_funcs[i].prop);
+                       while (p[j] != ':' && p[j] != ';' && p[j] != '\n' && p[j] != '\0') {
+                               buf[j] = p[j];
+                               j++;
+                       }
+                       if (p[j] != '\0') {
+                               buf[j] = '\0';
+                       }
+
+                       p += j;
+                       _optional_funcs[i].func(encoding, buf);
+                       break;
+               } else {
+
+               }
+       }
+}
+
+static int __cal_vcalendar_parse_location(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int i, j;
+       int ret;
+       int len;
+       int out;
+       int mode;
+       int charset, encoding;
+       char buf[64] = {0};
+       char *p = (char *)data;
+
+       i = j = 0;
+       out = 0;
+       mode = 0;
+       charset = encoding = 0;
+       while (p[i] != '\0') {
+               switch (p[i]) {
+               case ':':
+                       mode = 1;
+                       out = 1;
+                       break;
+
+               case ';':
+                       buf[j] = '\0';
+                       mode = __work_description_switch(2, mode, buf, &charset, &encoding);
+                       j = 0;
+                       break;
+
+               default:
+                       buf[j] = p[i];
+                       j++;
+                       break;
+               }
+               i++;
+
+               if (out) {
+                       DBG("out");
+                       break;
+               }
+       }
+       __work_description_switch(0, mode, buf, &charset, &encoding);
+
+       DBG("charset(%d) encoding(%d)", charset, encoding);
+       if (encoding) {
+               __cal_vcalendar_parse_decode_quoted_printable(p+i, &len);
+       }
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_str(record, _calendar_event.location, p + i);
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_str(record, _calendar_todo.location, p + i);
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_priority(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       char *p = (char *)data;
+
+       p++;
+       if (p[0] < '0' || p[0] > '9') {
+               DBG("warning check range\n");
+               return -1;
+       }
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_int(record, _calendar_event.priority, atoi(p));
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_int(record, _calendar_todo.priority, atoi(p));
+               break;
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_status(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       int status;
+       char *p = (char *)data;
+
+       p++;
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               if (!strncmp(p, "TENTATIVE", strlen("TENTATIVE")))
+               {
+                       status = CALENDAR_EVENT_STATUS_TENTATIVE;
+               }
+               else if (!strncmp(p, "CONFIRMED", strlen("CONFIRMED")))
+               {
+                       status = CALENDAR_EVENT_STATUS_CONFIRMED;
+               }
+               else if (!strncmp(p, "CANCELLED", strlen("CANCELLED")))
+               {
+                       status = CALENDAR_EVENT_STATUS_CANCELLED;
+               }
+               else
+               {
+                       status = CALENDAR_EVENT_STATUS_NONE;
+               }
+               ret = _cal_record_set_int(record, _calendar_event.event_status, status);
+
+               break;
+
+       case CALENDAR_BOOK_TYPE_TODO:
+               if (!strncmp(p, "NEEDS-ACTION", strlen("NEEDS-ACTION"))) // for ver2.0
+               {
+                       status = CALENDAR_TODO_STATUS_NEEDS_ACTION;
+               }
+               else if (!strncmp(p, "NEEDS ACTION", strlen("NEEDS ACTION"))) // for ver1.0
+               {
+                       status = CALENDAR_TODO_STATUS_NEEDS_ACTION;
+               }
+               else if (!strncmp(p, "COMPLETED", strlen("COMPLETED")))
+               {
+                       status = CALENDAR_TODO_STATUS_COMPLETED;
+               }
+               else if (!strncmp(p, "IN-PROCESS", strlen("IN-PROCESS")))
+               {
+                       status = CALENDAR_TODO_STATUS_IN_PROCESS;
+               }
+               else if (!strncmp(p, "CANCELLED", strlen("CANCELLED")))
+               {
+                       status = CALENDAR_TODO_STATUS_CANCELED;
+               }
+               else
+               {
+                       status = CALENDAR_TODO_STATUS_NONE;
+               }
+               ret = _cal_record_set_int(record, _calendar_todo.todo_status, status);
+
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_summary(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       int i, j;
+       int len;
+       int out;
+       int mode;
+       int charset, encoding;
+       char buf[64] = {0};
+       char *p = (char *)data;
+
+       i = j = 0;
+       out = 0;
+       mode = 0;
+       charset = encoding = 0;
+       while (p[i] != '\0') {
+               switch (p[i]) {
+               case ':':
+                       mode = 1;
+                       out = 1;
+                       break;
+
+               case ';':
+                       buf[j] = '\0';
+                       mode = __work_description_switch(2, mode, buf, &charset, &encoding);
+                       j = 0;
+                       break;
+
+               default:
+                       buf[j] = p[i];
+                       j++;
+                       break;
+               }
+               i++;
+
+               if (out) {
+                       break;
+               }
+       }
+       __work_description_switch(0, mode, buf, &charset, &encoding);
+
+       DBG("charset(%d) encoding(%d)", charset, encoding);
+       if (encoding) {
+               __cal_vcalendar_parse_decode_quoted_printable(p+i, &len);
+       }
+
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_str(record, _calendar_event.summary, p + i);
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_str(record, _calendar_todo.summary, p + i);
+               break;
+       }
+
+       DBG("summary(%s)\n", p + i);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_rrule(int ver, calendar_list_h list, calendar_record_h event, void *data)
+{
+       int ret;
+       int i, j, k;
+       int mode;
+       int version = 0;
+       char buf[64] = {0};
+       char *tzid;
+       char *p = (char *)data;
+
+       i = j = 0;
+       mode = 0;
+
+       if (strstr(p, "FREQ=")) {
+               DBG("This is version 2");
+               version = 2;
+       } else {
+               DBG("This is version 1");
+               version = 1;
+       }
+
+       if (version == 2) {
+               i = j = 0;
+               ret = _cal_record_set_int(event, _calendar_event.interval, 1);
+               /* this is for ver 2 */
+               while (p[i] != '\0') {
+                       DBG("[%c](%d)", p[i], i);
+                       switch (p[i]) {
+                       case ':':
+                       case ';':
+                               buf[j] = '\0';
+                               if (strlen(buf) < 1) {
+                                       break;
+                               }
+
+                               for (k = 0; k < RRULE_MAX; k++) {
+                                       if (!strncmp(buf, _rrule_funcs[k].prop, strlen(_rrule_funcs[k].prop))) {
+                                               _rrule_funcs[k].func(event, buf + strlen(_rrule_funcs[k].prop));
+                                               break;
+                                       }
+                               }
+                               j = 0;
+                               break;
+
+                       default:
+                               buf[j] = p[i];
+                               j++;
+                               break;
+                       }
+                       i++;
+               }
+
+               buf[j] = '\0';
+               for (i = 0; i < RRULE_MAX; i++) {
+                       if (!strncmp(buf, _rrule_funcs[i].prop, strlen(_rrule_funcs[i].prop))) {
+                               version = 2;
+                               _rrule_funcs[i].func(event, buf + strlen(_rrule_funcs[i].prop));
+                               break;
+                       }
+               }
+               return CALENDAR_ERROR_NONE;
+       }
+
+       /* this is for ver 1 */
+       int freq = 0;
+       int interval;
+       char by[64] = {0};
+       char _by[64] = {0};
+       char date[8] = {0};
+       int tmp;
+       int is_wday = 0;
+       int y, mon, d, h, min, s;
+       char t, z;
+       calendar_time_s stime;
+       i = 0;
+       mode = 0;
+       interval = 0;
+
+       ret = calendar_record_get_str(event, _calendar_event.start_tzid, &tzid);
+       ret = calendar_record_get_caltime(event, _calendar_event.start_time, &stime);
+
+       while (p[i] != '\0') {
+               switch (p[i]) {
+               case ':':
+               case ' ':
+                       if (mode == 0) {
+                               DBG("in mode 1");
+                               mode = 1;
+
+                       } else if (mode == 1) {
+                               DBG("in mode 2");
+                               mode = 2;
+                               buf[j] = '\0';
+                               if (buf[0] == 'D') {
+                                       freq = CALENDAR_RECURRENCE_DAILY;
+
+                               } else if (buf[0] == 'W') {
+                                       freq = CALENDAR_RECURRENCE_WEEKLY;
+
+                               } else if (buf[0] == 'M') {
+                                       freq = CALENDAR_RECURRENCE_MONTHLY;
+
+                               } else if (buf[0] == 'Y') {
+                                       freq = CALENDAR_RECURRENCE_YEARLY;
+
+                               } else {
+                                       freq = CALENDAR_RECURRENCE_NONE;
+
+                               }
+                               ret = _cal_record_set_int(event, _calendar_event.freq, freq);
+
+                               if (buf[1] >= '1' && buf[1] <= '9') {
+                                       interval = atoi(&buf[1]);
+                               } else {
+                                       interval = atoi(&buf[2]);
+                               }
+                               DBG("interval(%d)", interval);
+                               ret = _cal_record_set_int(event, _calendar_event.interval, interval);
+                               memset(buf, 0x0, sizeof(buf));
+
+                       } else {
+                               mode = 3;
+                               DBG("in mode 3");
+                               DBG("remained buf[%s]", buf);
+
+
+                               DBG("len(%d)", strlen(by));
+                               if (strlen(by) < 1) {
+                                       DBG("ret(%d)", atoi(buf));
+                                       if (buf[0] >= '1' && buf[0] <= '9') {
+                                               DBG("Set digit");
+                                               is_wday = 0;
+                                       } else {
+                                               DBG("Set wday [%s]", buf);
+                                               is_wday = 1;
+                                       }
+                                       DBG("1[%s][%s]", by, buf);
+                                       snprintf(_by, sizeof(by), "%s", buf);
+
+                               } else {
+                                       DBG("2[%s][%s]", by, buf);
+                                       snprintf(_by, sizeof(by), "%s %s", by, buf);
+                               }
+                               memcpy(by, _by, sizeof(_by));
+
+
+                               buf[j] = '\0';
+                               DBG("end statement[%s]", buf);
+                               DBG("freq(%d}", freq);
+                               switch (freq) {
+                               case CALENDAR_RECURRENCE_YEARLY:
+                                       ret = _cal_record_set_str(event, _calendar_event.bymonth, by);
+                                       _cal_time_ltoi(tzid, stime.time.utime, NULL, NULL, &tmp);
+                                       snprintf(date, sizeof(date), "%d", tmp);
+                                       ret = _cal_record_set_str(event, _calendar_event.bymonthday, date);
+                                       break;
+
+                               case CALENDAR_RECURRENCE_MONTHLY:
+                                       _cal_time_ltoi(tzid, stime.time.utime, NULL, &tmp, NULL);
+                                       snprintf(date, sizeof(date), "%d", tmp);
+                                       ret = _cal_record_set_str(event, _calendar_event.bymonth, date);
+
+                                       if (is_wday) {
+                                               ret = _cal_record_set_str(event, _calendar_event.byday, by);
+                                       } else {
+                                               ret = _cal_record_set_str(event, _calendar_event.bymonthday, by);
+                                       }
+                                       break;
+
+                               case CALENDAR_RECURRENCE_WEEKLY:
+                                       DBG("set weekly[%s]", by);
+                                       ret = _cal_record_set_str(event, _calendar_event.byday, by);
+                                       break;
+
+                               case CALENDAR_RECURRENCE_DAILY:
+                                       DBG("set daily[%s]", by);
+                                       ret = _cal_record_set_str(event, _calendar_event.byday, by);
+                                       break;
+                               default:
+                                       DBG("Nothing to set");
+                                       break;
+                               }
+                       }
+                       j = 0;
+                       memset(buf, 0x0, sizeof(buf));
+                       break;
+
+               default:
+                       buf[j] = p[i];
+                       j++;
+                       break;
+               }
+               i++;
+       }
+
+       DBG("freq(%d) interval(%d) by[%s]", freq, interval, by);
+
+       i = 0;
+       DBG("buf[%s]", buf);
+       calendar_time_s caltime = {0};
+       if (buf[i] == '#') {
+               if (buf[i + 1] == '0')
+               {
+                       DBG("count 0 and means endless");
+                       ret = _cal_record_set_int(event, _calendar_event.range_type,
+                                       CALENDAR_RANGE_NONE);
+               }
+               else
+               {
+                       DBG("until count [%s]", &buf[i+1]);
+                       ret = _cal_record_set_int(event, _calendar_event.range_type,
+                                       CALENDAR_RANGE_COUNT);
+                       ret = _cal_record_set_int(event, _calendar_event.count,
+                                       atoi(&buf[i+1]));
+               }
+
+       } else {
+               ret = _cal_record_set_int(event, _calendar_event.range_type,
+                               CALENDAR_RANGE_UNTIL);
+               DBG("untiltime[%s]", &buf[i]);
+               sscanf(&buf[i], "%4d%2d%2d%c%2d%2d%2d%c",
+                               &y, &mon, &d, &t, &h, &min, &s, &z);
+               caltime.type = CALENDAR_TIME_UTIME;
+               caltime.time.utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+               ret = _cal_record_set_caltime(event, _calendar_event.until_time, caltime);
+       }
+
+       CAL_FREE(tzid);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_dtend(int type, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       char *p = (char *)data;
+       int k = 0, j;
+       char buf[64] = {0, };
+       char *tzid = NULL;
+       calendar_time_s end;
+
+       p++;
+
+       int is_quot = 0;
+       if (!strncmp(p, "TZID=", strlen("TZID="))) {
+               k = 0;
+               j = strlen("TZID=");
+               while ((p[j] != ':' && p[j] != ';' && p[j] != '\n' && p[j] != '\0') || is_quot == 1) {
+
+                       if (p[j] == '\"' && is_quot == 0)
+                       {
+                               is_quot = 1;
+                               j++; // remove double quotation
+                       }
+                       else if (p[j] == '\"' && is_quot == 1)
+                       {
+                               is_quot = 0;
+                               j++;
+                               break;
+                       }
+                       else
+                       {
+                       }
+
+                       buf[k] = p[j];
+                       k++;
+                       j++;
+               }
+               if (p[j] != '\0') {
+                       buf[k] = '\0';
+               }
+               p += j;
+               p++;
+       } else {
+               snprintf(buf, sizeof(buf), "%s", CAL_TZID_GMT);
+       }
+       tzid = strdup(buf);
+
+       if (!strncmp(p, "VALUE=", strlen("VALUE="))) {
+               k = 0;
+               j = strlen("VALUE=");
+               while (p[j] != ':' && p[j] != ';' && p[j] != '\n' && p[j] != '\0') {
+                       buf[k] = p[j];
+                       k++;
+                       j++;
+               }
+               if (p[j] != '\0') {
+                       buf[k] = '\0';
+               }
+               p += j;
+               p++;
+       }
+
+       int y, mon, d, h, min, s;
+       char t, z;
+
+       if (!strncmp(buf, "DATE", strlen("DATE"))){
+               end.type = CALENDAR_TIME_LOCALTIME;
+
+               sscanf(p, "%4d%2d%2d", &y, &mon, &d);
+               end.time.date.year = y;
+               end.time.date.month = mon;
+               end.time.date.mday = d;
+
+       } else {
+               end.type = CALENDAR_TIME_UTIME;
+
+               sscanf(p, "%4d%2d%2d%c%2d%2d%2d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
+
+               if (strlen(p) != strlen("YYYYMMDDTHHMMSS"))
+               {
+                       end.time.utime = _cal_time_convert_itol(NULL, y, mon, d, h, min, s);
+               }
+               else
+               {
+                       char *like_tzid = NULL;
+                       if (_cal_time_is_registered_tzid(tzid))
+                       {
+                               end.time.utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+                       }
+                       else
+                       {
+                               calendar_record_h timezone = NULL;
+                               // try get timezone info from the list
+                               __cal_vcalendar_parse_get_tzid_from_list(list, tzid, &timezone);
+                               if (timezone)
+                               {
+                                       DBG("Found from the list");
+                                       _cal_time_get_like_tzid(tzid, timezone, &like_tzid);
+                                       end.time.utime = _cal_time_convert_itol(like_tzid, y, mon, d, h, min, s);
+                                       DBG("[%s]", like_tzid);
+                                       CAL_FREE(like_tzid);
+                                       like_tzid = NULL;
+                               }
+                               else
+                               {
+                                       DBG("Nowhere to find");
+                                       end.time.utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+                               }
+                       }
+               }
+       }
+       switch (type)
+       {
+       case CALENDAR_BOOK_TYPE_EVENT:
+               ret = _cal_record_set_str(record, _calendar_event.end_tzid, tzid);
+               ret = _cal_record_set_caltime(record, _calendar_event.end_time, end);
+               break;
+       case CALENDAR_BOOK_TYPE_TODO:
+               ret = _cal_record_set_str(record, _calendar_todo.due_tzid, tzid);
+               ret = _cal_record_set_caltime(record, _calendar_todo.due_time, end);
+               break;
+       }
+       CAL_FREE(tzid);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_completed(int ver, calendar_list_h list, calendar_record_h event, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_percent(int ver, calendar_list_h list, calendar_record_h event, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+/////////////////////////////////////////////////////////////////
+static int __cal_vcalendar_parse_attendee_cutype(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_member(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_role(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_partstat(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_rsvp(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_delto(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_delfrom(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_sentby(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_cn(calendar_record_h attendee, void *data)
+{
+       int ret;
+       int i = 0;
+       char *text = NULL;
+       char *p = (char *)data;
+
+       while (*p != ':' && *p != '\n' && *p != '\r' && *p != '\0') {
+               i++;
+               p++;
+       }
+
+       text = calloc(i + 1, sizeof(char));
+       if (text == NULL) {
+               ERR("Failed to calloc");
+               return -1;
+       }
+       snprintf(text, i + 1, "%s", (char *)data);
+
+       ret = _cal_record_set_str(attendee, _calendar_attendee.name, text);
+       DBG("cn[%s]", text);
+       if (text) free(text);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee_dir(calendar_record_h attendee, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+int _work_attendee_mailto(calendar_record_h attendee, char *buf)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+int _work_attendee_property(calendar_record_h attendee, char *buf)
+{
+       int i;
+       int len_all, len_prop;
+
+       for (i = 0; i < ATTENDEE_MAX; i++) {
+               if (!strncmp(buf, _attendee_funcs[i].prop, strlen(_attendee_funcs[i].prop))) {
+                       len_all = strlen(buf);
+                       len_prop = strlen(_attendee_funcs[i].prop);
+                       snprintf(buf, len_all - len_prop + 1, "%s", &buf[len_prop]);
+                       _attendee_funcs[i].func(attendee, buf);
+                       break;
+               }
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attendee(int ver, calendar_list_h list, calendar_record_h event, void *data)
+{
+       int ret;
+       int i, j;
+       char *p = (char *)data;
+       calendar_record_h attendee;
+
+       ret = calendar_record_create(_calendar_attendee._uri, &attendee);
+
+       ret = calendar_record_add_child_record(event, _calendar_event.calendar_attendee, attendee);
+
+       i = 0;
+       j = 0;
+       int mode = 0;
+       char buf[64] = {0};
+
+       while (p[i] != '\0') {
+               switch (p[i]) {
+               case ':':
+                       /* work mail to */
+                       if (mode) {
+                               buf[j] = '\0';
+                               _work_attendee_mailto(attendee, buf);
+                               mode = 0;
+                       } else {
+                               mode = 1;
+                       }
+                       j = 0;
+                       break;
+
+               case ';':
+                       /* work property */
+                       if (mode) {
+                               buf[j] = '\0';
+                               _work_attendee_property(attendee, buf);
+                               mode = 0;
+                       } else {
+                               mode = 2;
+                       }
+                       j = 0;
+                       break;
+
+               default:
+                       buf[j] = p[i];
+                       j++;
+                       break;
+               }
+               i++;
+       }
+
+       switch (mode) {
+       case 1:
+               buf[j] = '\0';
+               _work_attendee_mailto(attendee, buf);
+               break;
+       case 2:
+               buf[j] = '\0';
+               _work_attendee_property(attendee, buf);
+               break;
+       default:
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+
+static int __cal_vcalendar_parse_categories(int ver, calendar_list_h list, calendar_record_h event, void *data)
+{
+       char *p = (char *)data;
+       int encoding = 0;
+
+       while (*p != '\n' && *p != '\r' && *p != '\0') {
+               if ( *p == ':') {
+                       p++;
+                       if (encoding == ENCODE_BASE64) {
+                               gsize len;
+                               _cal_record_set_str(event, _calendar_event.categories,
+                                               (char *)g_base64_decode(p, &len));
+
+                       } else if (encoding == ENCODE_QUOTED_PRINTABLE) {
+                               int len;
+                               __cal_vcalendar_parse_decode_quoted_printable(p, &len);
+                               _cal_record_set_str(event, _calendar_event.categories, p);
+
+                       } else {
+                               _cal_record_set_str(event, _calendar_event.categories, p);
+                       }
+                       break;
+
+               } else if (*p == ';') {
+                       p++;
+                       __cal_vcalendar_parse_get_optional(p, &encoding);
+
+               } else {
+                       p++;
+               }
+       }
+       DBG("ver(%d)categories(%s)\n", ver, p);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+/*
+   For ver 1.0 aalarm
+   alarmparts  = 0*3(strnosemi ";") strnosemi
+   ; runTime, snoozeTime, repeatCount, audioContent
+*/
+enum {
+       __AALARM_INVALID = 0,
+       __AALARM_RUNTIME,
+       __AALARM_TYPE,
+       __AALARM_VALUE,
+       __AALARM_SNOOZETIME,
+       __AALARM_REPEATCOUNT,
+       __AALARM_AUDIOCONTENT,
+};
+static int __cal_vcalendar_parse_aalarm(int ver, calendar_list_h list, calendar_record_h record, void *data)
+{
+       int ret;
+       int i = 0, j = 0;
+       int part = 0;
+       int y, mon, d, h, min, s;
+       char t, z;
+       char buf[64] = {0};
+       char *p = (char *)data;
+
+       while (p[i] != '\0')
+       {
+               // select part
+               switch (p[i])
+               {
+               case ':':
+                       i++;
+                       part = __AALARM_RUNTIME;
+                       break;
+
+               case ';':
+                       i++;
+                       if (!strncmp(p, "TYPE=", strlen("TYPE=")))
+                       {
+                               part = __AALARM_TYPE;
+                       }
+                       else if (!strncmp(p, "VALUE=", strlen("VALUE=")))
+                       {
+                               part = __AALARM_VALUE;
+                       }
+                       else if (p[i] == 'P')
+                       {
+                               part = __AALARM_SNOOZETIME; // Period
+                       }
+                       else if (p[i] >= '0' && p[i] < '9')
+                       {
+                               part = __AALARM_REPEATCOUNT; // repeatCount
+                       }
+                       else
+                       {
+                               part = __AALARM_AUDIOCONTENT;
+                       }
+                       break;
+
+               default:
+                       ERR("Error");
+                       i++;
+                       break;
+               }
+
+               // extract value
+               j = 0;
+               while (p[i] != '\0' && p[i] != ':' && p[i] != ';')
+               {
+                       buf[j] = p[i];
+                       j++;
+                       i++;
+               }
+               buf[j] = '\0';
+
+               DBG("part(%d) value[%s]", part, buf);
+               // work part
+               switch (part)
+               {
+               case __AALARM_INVALID:
+                       break;
+
+               case __AALARM_RUNTIME:
+                       y = mon = d = h = min = s = 0;
+                       sscanf(buf, "%04d%02d%02d%c%02d%02d%02d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
+                       DBG("%d %d %d %d %d %d", y, mon, d, h, min, s);
+                       break;
+
+               case __AALARM_TYPE:
+                       break;
+
+               case __AALARM_VALUE:
+                       break;
+
+               case __AALARM_SNOOZETIME:
+                       break;
+
+               case __AALARM_REPEATCOUNT:
+                       break;
+
+               case __AALARM_AUDIOCONTENT:
+                       break;
+
+               }
+       }
+
+       char *tzid = NULL;
+       long long int run_utime = 0;
+       int diff = 0;
+       int tick = 0, unit = 0;
+       calendar_record_h alarm = NULL;
+       calendar_time_s caltime = {0};
+       switch (ver)
+       {
+       case VCALENDAR_TYPE_VEVENT:
+               ret = calendar_record_get_caltime(record, _calendar_event.start_time, &caltime);
+               if (z != 'Z')
+               {
+                       ret = calendar_record_get_str_p(record, _calendar_event.start_tzid, &tzid);
+                       run_utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+                       if (tzid) free(tzid);
+               }
+               else
+               {
+                       run_utime = _cal_time_convert_itol(NULL, y, mon, d, h, min, s);
+               }
+
+               switch (caltime.type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       diff = (int)(caltime.time.utime - run_utime);
+                       DBG("diff(%d) = (%lld) - (%lld)", diff, caltime.time.utime, run_utime);
+
+                       if (diff / (60 * 60 * 24 * 7) > 0)
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_WEEK;
+                               tick = diff /(60 * 60 * 24 * 7);
+                       }
+                       else if (diff / (60 * 60 * 24 ) > 0)
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_DAY;
+                               tick = diff /(60 * 60 * 24);
+                       }
+                       else if (diff / (60 * 60) > 0)
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_HOUR;
+                               tick = diff / (60 * 60);
+                       }
+                       else
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_MINUTE;
+                               tick = diff / 60;
+                       }
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       break;
+               }
+
+               ret = calendar_record_create(_calendar_alarm._uri, &alarm);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_create() failed");
+                       return ret;
+               }
+               calendar_record_set_int(alarm, _calendar_alarm.tick, tick);
+               calendar_record_set_int(alarm, _calendar_alarm.tick_unit, unit);
+               calendar_record_add_child_record(record, _calendar_event.calendar_alarm, alarm);
+               break;
+
+       case VCALENDAR_TYPE_VTODO:
+               ret = calendar_record_get_caltime(record, _calendar_todo.due_time, &caltime);
+               if (z != 'Z')
+               {
+                       ret = calendar_record_get_str_p(record, _calendar_todo.due_tzid, &tzid);
+                       run_utime = _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+                       if (tzid) free(tzid);
+               }
+               else
+               {
+                       run_utime = _cal_time_convert_itol(NULL, y, mon, d, h, min, s);
+               }
+
+               switch (caltime.type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       diff = (int)(caltime.time.utime - run_utime);
+
+                       if (diff / (60 * 60 * 24 * 7) > 0)
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_WEEK;
+                               tick = diff /(60 * 60 * 24 * 7);
+                       }
+                       else if (diff / (60 * 60 * 24 ) > 0)
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_DAY;
+                               tick = diff /(60 * 60 * 24);
+                       }
+                       else if (diff / (60 * 60) > 0)
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_HOUR;
+                               tick = diff / (60 * 60);
+                       }
+                       else
+                       {
+                               unit = CALENDAR_ALARM_TIME_UNIT_MINUTE;
+                               tick = diff / 60;
+                       }
+                       break;
+
+                       break;
+               case CALENDAR_TIME_LOCALTIME:
+                       break;
+               }
+               ret = calendar_record_create(_calendar_alarm._uri, &alarm);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_create() failed");
+                       return ret;
+               }
+               calendar_record_set_int(alarm, _calendar_alarm.tick, tick);
+               calendar_record_set_int(alarm, _calendar_alarm.tick_unit, unit);
+               calendar_record_add_child_record(record, _calendar_todo.calendar_alarm, alarm);
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+/* end */
+
+
+enum {
+       WEEKNAME2_SA = 0x0,
+       WEEKNAME2_FR,
+       WEEKNAME2_TH,
+       WEEKNAME2_WE,
+       WEEKNAME2_TU,
+       WEEKNAME2_MO,
+       WEEKNAME2_SU,
+       WEEKNAME2_MAX,
+};
+const char weekname2[WEEKNAME2_MAX][3] = {"SA", "FR", "TH", "WE", "TU", "MO", "SU"};
+
+//alarm////////////////////////////////////////////////////////////
+static int __cal_vcalendar_parse_action(calendar_record_h alarm, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static char *__cal_vcalendar_parse_extract_duration(char *p, int *dur_t, char *dur)
+{
+       char du = '0';
+       char buf[8] = {0, };
+       int i = 0, c, d = 1;
+       int t = 0;
+
+       DBG("%s", p);
+       while (*p != '\0' && *p != '\n') {
+               switch (*p) {
+               case '+':
+                       d = 1;
+                       break;
+               case '-':
+                       d = -1;
+                       break;
+               case 'P':
+                       i = 0;
+                       break;
+               case 'T':
+                       break;
+               case 'W':
+                       du = 'W';
+                       c = atoi(buf);
+                       t += c * 7 * 24 * 60 * 60;
+                       memset(buf, 0x0, sizeof(buf));
+                       i = 0;
+                       break;
+               case 'D':
+                       du = 'D';
+                       c = atoi(buf);
+                       t += c * 24 * 60 * 60;
+                       memset(buf, 0x0, sizeof(buf));
+                       i = 0;
+                       break;
+               case 'H':
+                       du = 'H';
+                       c = atoi(buf);
+                       t += c * 60 * 60;
+                       memset(buf, 0x0, sizeof(buf));
+                       i = 0;
+                       break;
+               case 'M':
+                       du = 'M';
+                       c = atoi(buf);
+                       t += c * 60;
+                       memset(buf, 0x0, sizeof(buf));
+                       i = 0;
+                       break;
+               case 'S':
+                       du = 'S';
+                       c = atoi(buf);
+                       t += c;
+                       memset(buf, 0x0, sizeof(buf));
+                       i = 0;
+                       break;
+               default:
+                       buf[i] = *p;
+                       i++;
+                       break;
+
+               }
+               p++;
+       }
+       t *= d;
+       *dur_t = t;
+
+       if (dur) {
+               *dur = du;
+       }
+
+       return p;
+}
+
+static int __cal_vcalendar_parse_trigger_time(calendar_record_h alarm, char *p)
+{
+       char t = 0, z;
+       int y, mon, d, h, min, s;
+       int tick, unit;
+       cal_alarm_s *_alarm = (cal_alarm_s *)alarm;
+
+       if (NULL == alarm || NULL == p)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       sscanf(p, "%4d%2d%2d%c%2d%2d%2d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
+
+       tick = _alarm->remind_tick;
+       unit = _alarm->remind_tick_unit;
+       switch (unit)
+       {
+       case CALENDAR_ALARM_TIME_UNIT_WEEK:
+               mon += tick;
+               break;
+       case CALENDAR_ALARM_TIME_UNIT_DAY:
+               d += tick;
+               break;
+       case CALENDAR_ALARM_TIME_UNIT_HOUR:
+               h += tick;
+               break;
+       case CALENDAR_ALARM_TIME_UNIT_MINUTE:
+               min += tick;
+               break;
+       case CALENDAR_ALARM_TIME_UNIT_SPECIFIC:
+       default:
+               break;
+       }
+
+       if (t == 0)
+       {
+               int datetime = y *10000 + mon *100 + d;
+               _cal_record_set_lli(alarm, _calendar_alarm.time, datetime);
+               DBG("DATE(%d)", datetime);
+       }
+       else
+       {
+               long long int lli = _cal_time_convert_itol(NULL, y, mon, d, h, min, s);
+               _cal_record_set_lli(alarm, _calendar_alarm.time, lli);
+               DBG("DATE-TIME(%lld)", lli);
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_duration_alarm(calendar_record_h alarm, void *data)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       char *p = (char *)data;
+       char dur;
+       int dur_t;
+       int tick, unit;
+
+       p++;
+
+       __cal_vcalendar_parse_extract_duration(p, &dur_t, &dur);
+       switch (dur) {
+       case 'W':
+               tick = dur_t/(7 *24 *60 *60);
+               unit = CALENDAR_ALARM_TIME_UNIT_WEEK;
+               break;
+       case 'D':
+               tick = dur_t/(24 *60 *60);
+               unit = CALENDAR_ALARM_TIME_UNIT_DAY;
+               break;
+       case 'H':
+               tick = dur_t/(60 *60);
+               unit = CALENDAR_ALARM_TIME_UNIT_HOUR;
+               break;
+       case 'M':
+               tick = dur_t/(60);
+               unit = CALENDAR_ALARM_TIME_UNIT_MINUTE;
+               break;
+       default:
+               tick = 1;
+               unit = CALENDAR_ALARM_NONE;;
+               break;
+       }
+
+       ret = _cal_record_set_int(alarm, _calendar_alarm.tick, tick);
+       ret = _cal_record_set_int(alarm, _calendar_alarm.tick_unit, unit);
+       DBG("tick(%d) unit(%d)", tick, unit);
+
+       return ret;
+}
+
+static int __cal_vcalendar_parse_trigger(calendar_record_h alarm, void *data)
+{
+       int i = 0, out = 0;
+       char *p = (char *)data;
+
+       p++;
+
+       // default unit
+       _cal_record_set_int(alarm, _calendar_alarm.tick_unit, CALENDAR_ALARM_TIME_UNIT_SPECIFIC);
+
+       while (*p != '\n' && *p != '\r' && *p != '\0') {
+
+               for (i = 0; i < TRIG_MAX; i++) {
+                       if (!strncmp(p, _trig_funcs[i].prop, strlen(_trig_funcs[i].prop))) {
+                               out = 1;
+                               int j = 0;
+                               char buf[64] = {0, };
+                               p += strlen(_trig_funcs[i].prop);
+                               while (p[j] != ';' && p[j] != '\n' && p[j] != '\0') {
+                                       buf[j] = p[j];
+                                       j++;
+                               }
+                               if (p[j] != '\0') {
+                                       buf[j] = '\0';
+                               }
+
+                               p += j;
+                               _trig_funcs[i].func(alarm, buf);
+                               break;
+                       }
+               }
+               if (out == 1) {
+                       break;
+               }
+
+               if (*p >= '1'  && *p <= '9')
+               {
+                       __cal_vcalendar_parse_trigger_time(alarm, p);
+               }
+               else
+               {
+                       __cal_vcalendar_parse_duration_alarm(alarm, p);
+               }
+               break;
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_repeat(calendar_record_h alarm, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_attach_alarm(calendar_record_h alarm, void *data)
+{
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_summary_alarm(calendar_record_h alarm, void *data)
+{
+       int ret;
+       char *p = (char *)data;
+
+       p++;
+
+       ret = _cal_record_set_str(alarm, _calendar_alarm.description, p);
+       DBG("alarm description[%s]", p);
+       return CALENDAR_ERROR_NONE;
+}
+
+
+//rrule////////////////////////////////////////////////////////////
+static int __cal_vcalendar_parse_freq(calendar_record_h event, void *data)
+{
+       int ret;
+       int freq = -1;
+       char *p = (char *)data;
+
+       DBG("%s\n", (char *)data);
+       if (!strncmp(p, "YEARLY", strlen("YEARLY"))) {
+               freq = CALENDAR_RECURRENCE_YEARLY;
+
+       } else if (!strncmp(p, "MONTHLY", strlen("MONTHLY"))) {
+               freq = CALENDAR_RECURRENCE_MONTHLY;
+
+       } else if (!strncmp(p, "WEEKLY", strlen("WEEKLY"))) {
+               freq = CALENDAR_RECURRENCE_WEEKLY;
+
+       } else if (!strncmp(p, "DAILY", strlen("DAILY"))) {
+               freq = CALENDAR_RECURRENCE_DAILY;
+
+       } else if (!strncmp(p, "HOURLY", strlen("HOURLY"))) {
+               freq = CALENDAR_RECURRENCE_NONE;
+
+       } else if (!strncmp(p, "MINUTELY", strlen("MINUTELY"))) {
+               freq = CALENDAR_RECURRENCE_NONE;
+
+       } else if (!strncmp(p, "SECONDLY", strlen("SECONDLY"))) {
+               freq = CALENDAR_RECURRENCE_NONE;
+
+       } else {
+               freq = CALENDAR_RECURRENCE_NONE;
+
+       }
+       ret = _cal_record_set_int(event, _calendar_event.freq, freq);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_until(calendar_record_h event, void *data)
+{
+       int ret;
+       calendar_time_s stime;
+       calendar_time_s until;
+       int y, mon, d, h, min, s;
+       char *tzid;
+       char t, z;
+       char *p = (char *)data;
+
+       /* until value type has the same value as the dtstart */
+       ret = _cal_record_set_int(event, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
+
+       ret = calendar_record_get_str(event, _calendar_event.start_tzid, &tzid);
+       ret = calendar_record_get_caltime(event, _calendar_event.start_time, &stime);
+       until.type = stime.type;
+
+       switch (stime.type)
+       {
+       case CALENDAR_TIME_UTIME:
+               until.time.utime = _cal_time_convert_stol(tzid, p);
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               sscanf(p, "%4d%2d%2d%c%2d%2d%2d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
+               until.time.date.year = y;
+               until.time.date.month = mon;
+               until.time.date.mday = d;
+
+               break;
+       }
+       ret = _cal_record_set_caltime(event, _calendar_event.until_time, until);
+       CAL_FREE(tzid);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_count(calendar_record_h event, void *data)
+{
+       int ret;
+       int c;
+       char *p = (char *)data;
+
+       DBG("%s\n", (char *)data);
+       ret = _cal_record_set_int(event, _calendar_event.range_type, CALENDAR_RANGE_COUNT);
+       c = atoi(p);
+       ret = _cal_record_set_int(event, _calendar_event.count, c < 0 ? 0 : c);
+       return ret;
+}
+
+static int __cal_vcalendar_parse_interval(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       int c;
+       char *p = (char *)data;
+
+       c = atoi(p);
+       return _cal_record_set_int(event, _calendar_event.interval, c < 0 ? 0 : c);
+}
+
+static int __cal_vcalendar_parse_bysecond(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.bysecond, (char *)data);
+}
+
+static int __cal_vcalendar_parse_byminute(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.byminute, (char *)data);
+}
+
+static int __cal_vcalendar_parse_byhour(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.byhour, (char *)data);
+}
+
+static int __cal_vcalendar_parse_byday(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.byday, (char *)data);
+}
+
+static int __cal_vcalendar_parse_bymonthday(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.bymonthday, (char *)data);
+}
+
+static int __cal_vcalendar_parse_byyearday(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.byyearday, (char *)data);
+}
+
+static int __cal_vcalendar_parse_byweekno(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.byweekno, (char *)data);
+}
+
+static int __cal_vcalendar_parse_bymonth(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.bymonth, (char *)data);
+}
+
+static int __cal_vcalendar_parse_bysetpos(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return _cal_record_set_str(event, _calendar_event.bysetpos, (char *)data);
+}
+
+static int __cal_vcalendar_parse_wkst(calendar_record_h event, void *data)
+{
+       DBG("%s\n", (char *)data);
+       int wkst;
+       char *p = (char *)data;
+
+       if (!strncmp(p, "SU", strlen("SU"))) {
+               wkst = CALENDAR_SUNDAY;
+
+       } else if (!strncmp(p, "MO", strlen("MO"))) {
+               wkst = CALENDAR_MONDAY;
+
+       } else if (!strncmp(p, "TU", strlen("TU"))) {
+               wkst = CALENDAR_TUESDAY;
+
+       } else if (!strncmp(p, "WE", strlen("WE"))) {
+               wkst = CALENDAR_WEDNESDAY;
+
+       } else if (!strncmp(p, "TH", strlen("TH"))) {
+               wkst = CALENDAR_THURSDAY;
+
+       } else if (!strncmp(p, "FR", strlen("FR"))) {
+               wkst = CALENDAR_FRIDAY;
+
+       } else if (!strncmp(p, "SA", strlen("SA"))) {
+               wkst = CALENDAR_SATURDAY;
+
+       } else {
+               wkst = -1;
+       }
+       return _cal_record_set_int(event, _calendar_event.wkst, wkst);
+}
+
+static int __get_tick_unit(char *p, int *tick, int *unit)
+{
+       int d, c, i = 0; /* direct, const, i */
+       int t, u; /* tick, unit */
+       char buf[8] = {0};
+
+       t = 0;
+       c = 0;
+       u = CAL_SCH_TIME_UNIT_OFF;
+       while (*p != '\0' && *p != '\n') {
+               switch (*p) {
+               case '+':
+                       d = 1;
+                       break;
+               case '-':
+                       d = -1;
+                       break;
+               case 'P':
+                       i = 0;
+                       break;
+               case 'T':
+                       break;
+               case 'W':
+                       c = atoi(buf);
+                       DBG("W tick(%d)", c);
+                       if (c == 0) break;
+                       u = CALENDAR_ALARM_TIME_UNIT_WEEK;
+                       t += c;
+                       i = 0;
+                       break;
+               case 'D':
+                       c = atoi(buf);
+                       DBG("D tick(%d)", c);
+                       if (c == 0) break;
+                       u = CALENDAR_ALARM_TIME_UNIT_DAY;
+                       t += c;
+                       i = 0;
+                       break;
+               case 'H':
+                       c = atoi(buf);
+                       DBG("H tick(%d)", c);
+                       if (c == 0) break;
+                       u = CALENDAR_ALARM_TIME_UNIT_HOUR;
+                       t += c;
+                       i = 0;
+                       break;
+               case 'M':
+                       c = atoi(buf);
+                       DBG("M tick(%d)", c);
+                       if (c == 0) break;
+                       u = CALENDAR_ALARM_TIME_UNIT_MINUTE;
+                       t += c;
+                       i = 0;
+                       break;
+               case 'S':
+                       i = 0;
+                       break;
+               default:
+                       buf[i] = *p;
+                       i++;
+                       break;
+               }
+               p++;
+       }
+       if (t != c) {
+               u = CALENDAR_ALARM_TIME_UNIT_SPECIFIC;
+       }
+       *tick = t;
+       *unit = u;
+       DBG("get tic(%d) unit(%d)", t, u);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_trig_related(calendar_record_h alarm, void *data)
+{
+       DBG("%s\n", (char *)data);
+
+       int tick = 0, unit;
+       char *p = (char *)data;
+
+       if (p == NULL) {
+               return -1;
+       }
+
+       if (!strncmp(p, "START", strlen("START") + 1)) {
+               p += strlen("START") + 1;
+               DBG("related start and value[%s]", p);
+
+       } else if (!strncmp(p, "END", strlen("END") +1)) {
+               p += strlen("END") + 1;
+               DBG("related end and value[%s]", p);
+
+       } else {
+               DBG("no related and value[%s]", p);
+
+       }
+       __get_tick_unit(p, &tick, &unit);
+       _cal_record_set_int(alarm, _calendar_alarm.tick, tick);
+       _cal_record_set_int(alarm, _calendar_alarm.tick_unit, unit);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+long long int _get_utime_from_datetime(char *tzid, char *p)
+{
+       int y, mon, d, h, min, s;
+       int len;
+       char t, z;
+       if (p == NULL) {
+               return -1;
+       }
+       len = strlen(p);
+       if (len < strlen("YYYYMMDDTHHMMSS")) {
+               return -1;
+       }
+
+       sscanf(p, "%04d%02d%02d%c%02d%02d%02d%c",
+                       &y, &mon, &d, &t, &h, &min, &s, &z);
+
+       return _cal_time_convert_itol(tzid, y, mon, d, h, min, s);
+}
+
+static int __cal_vcalendar_parse_trig_value(calendar_record_h alarm, void *data)
+{
+       DBG("%s\n", (char *)data);
+
+       int ret;
+       char *p = (char *)data;
+
+       if (!strncmp(p, "DATE-TIME", strlen("DATE-TIME") + 1)) {
+               p += strlen("DATE-TIME") + 1;
+               ret = _cal_record_set_int(alarm, _calendar_alarm.tick_unit, CALENDAR_ALARM_TIME_UNIT_SPECIFIC);
+               ret = _cal_record_set_lli(alarm, _calendar_alarm.time, _cal_time_convert_stol(NULL, p));
+       } else {
+
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_charset(int *val, void *data)
+{
+       DBG("%s\n", (char *)data);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_encoding(int *val, void *data)
+{
+       char *p = (char *)data;
+       *val = 0;
+
+       if (!strncmp(p, "BASE64", strlen("BASE64"))) {
+               DBG("ENCODE_BASE64");
+               *val = ENCODE_BASE64;
+
+       } else if (!strncmp(p, "QUOTED-PRINTABLE", strlen("QUOTED-PRINTABLE"))){
+               DBG("ENCODE_QUOTED_PRINTABLE");
+               *val = ENCODE_QUOTED_PRINTABLE;
+
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+// end parse func////////////////////////////////////////////////////////////////
+
+char *_cal_vcalendar_parse_vevent(int ver, calendar_list_h *list_sch, void *data)
+{
+       DBG("[%s]", __func__);
+       int i;
+       int ret;
+       char *prop = NULL, *cont = NULL;
+       char *cursor = (char *)data;
+       calendar_record_h event = NULL;
+
+       ret = calendar_record_create(_calendar_event._uri, &event);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_create() failed");
+               return NULL;
+       }
+
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont))) {
+               if (!strncmp(cont + 1, "VALARM", strlen("VALARM"))) {
+                       if (!strncmp(cont + 1, "VALARM", strlen("VALARM"))) {
+                               cursor = _cal_vcalendar_parse_valarm(VCALENDAR_TYPE_VEVENT, event, cursor);
+                       } else {
+                               break;
+                       }
+
+               } else if (!strncmp(prop, "END", strlen("END"))) {
+                       break;
+
+               } else {
+                       for (i = 0; i < VEVE_MAX; i++) {
+                               if (!strncmp(prop, _vevent_funcs[i].prop, strlen(_vevent_funcs[i].prop))) {
+                                       _vevent_funcs[i].func(ver, *list_sch, event, cont);
+                                       break;
+                               }
+                       }
+               }
+
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+       }
+
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       DBG("event add to the list");
+       ret = calendar_list_add(*list_sch, event);
+
+       return cursor;
+}
+
+char *_cal_vcalendar_parse_vtodo(int type, calendar_list_h *list_sch, void *data)
+{
+       int i;
+       int ret;
+       char *prop = NULL, *cont = NULL;
+       char *cursor = (char *)data;
+       calendar_record_h todo = NULL;
+
+       ret = calendar_record_create(_calendar_todo._uri, &todo);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_create() failed");
+               return NULL;
+       }
+
+       /* do until meet BEGIN */
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont))) {
+               if (!strncmp(prop, "BEGIN", strlen("BEGIN"))) {
+
+                       if (!strncmp(cont + 1, "VALARM", strlen("VALARM"))) {
+                               cursor = _cal_vcalendar_parse_valarm(VCALENDAR_TYPE_VTODO, todo, cursor);
+                       } else {
+                               break;
+                       }
+
+               } else if (!strncmp(prop, "END", strlen("END"))) {
+                       break;
+
+               } else {
+                       for (i = 0; i < VTODO_MAX; i++) {
+                               if (!strncmp(prop, _vtodo_funcs[i].prop, strlen(_vtodo_funcs[i].prop))) {
+                                       _vtodo_funcs[i].func(type, *list_sch, todo, cont);
+                                       break;
+                               }
+                       }
+               }
+
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+       }
+
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       ret = calendar_list_add(*list_sch, todo);
+
+       return cursor;
+}
+
+char *_cal_vcalendar_parse_valarm(int type, calendar_record_h record, void *data)
+{
+       int ret;
+       int i;
+       char *prop = NULL, *cont = NULL;
+       char *cursor = (char *)data;
+       calendar_record_h alarm = NULL;
+
+       ret = calendar_record_create(_calendar_alarm._uri, &alarm);
+
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont))) {
+               if (!strncmp(prop, "BEGIN", strlen("BEGIN"))) {
+                       break;
+
+               } else if (!strncmp(prop, "END", strlen("END"))) {
+                       break;
+
+               }
+
+               for (i = 0; i < VALA_MAX; i++) {
+                       if (!strncmp(prop, _valarm_funcs[i].prop, strlen(_valarm_funcs[i].prop))) {
+                               _valarm_funcs[i].func(alarm, cont);
+                               break;
+                       }
+               }
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+       }
+
+       switch (type) {
+       case VCALENDAR_TYPE_VEVENT:
+               ret = calendar_record_add_child_record(record, _calendar_event.calendar_alarm, alarm);
+               break;
+       case VCALENDAR_TYPE_VTODO:
+               ret = calendar_record_add_child_record(record, _calendar_todo.calendar_alarm, alarm);
+               break;
+       }
+
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       return cursor;
+}
+
+/*
+ * parse vtimezone
+ */
+enum {
+       VTIMEZONE_STD_DTSTART = 0x0,
+       VTIMEZONE_STD_TZOFFSETFROM,
+       VTIMEZONE_STD_TZOFFSETTO,
+       VTIMEZONE_STD_MAX,
+};
+
+static int __cal_vcalendar_parse_vtimezone_std_dtstart(calendar_record_h timezone, void *data)
+{
+       int y, mon, d, h, min, s;
+       int nth = 0, wday = 0;
+       long long int utime;
+       char t, z;
+       char *p = (char *)data;
+
+       if (NULL == timezone)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       sscanf(p +1, "%04d%02d%02d%c%02d%02d%02d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
+       utime = _cal_time_convert_itol(NULL, y, mon, d, h, min, s);
+       _cal_time_ltoi2(NULL, utime, &nth, &wday);
+       DBG("timezone dtstart(%04d-%02d-%02d %02d:%02d:%02d", y, mon, d, h, min, s);
+       DBG("timezone day of week(%d/%d)", nth, wday);
+       _cal_record_set_int(timezone, _calendar_timezone.standard_start_month, mon);
+       _cal_record_set_int(timezone, _calendar_timezone.standard_start_position_of_week, nth);
+       _cal_record_set_int(timezone, _calendar_timezone.standard_start_day, wday);
+       _cal_record_set_int(timezone, _calendar_timezone.standard_start_hour, h);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_vtimezone_std_tzoffsetfrom(calendar_record_h timezone, void *data)
+{
+       return 0;
+}
+
+static int __cal_vcalendar_parse_vtimezone_std_tzoffsetto(calendar_record_h timezone, void *data)
+{
+       int h, m;
+       char *p = (char *)data;
+       char c;
+       cal_timezone_s *tz = (cal_timezone_s *)timezone;
+
+       if (NULL == timezone)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       sscanf(p +1, "%c%02d%02d", &c, &h, &m);
+       DBG("timezone standard offsetto(%c)(%02d)(%02d)", c, h, m);
+       if (c == '-')
+       {
+               h *= -1;
+       }
+       if (tz->day_light_bias)
+       {
+               // this means daylight is set before gmt offset
+               _cal_record_set_int(timezone, _calendar_timezone.day_light_bias,
+                               tz->day_light_bias - (h * 60 + m));
+       }
+       _cal_record_set_int(timezone, _calendar_timezone.tz_offset_from_gmt, h * 60 + m);
+       return CALENDAR_ERROR_NONE;
+}
+
+struct _record_func _vtimezone_std[VTIMEZONE_STD_MAX] =
+{
+       {"DTSTART", __cal_vcalendar_parse_vtimezone_std_dtstart },
+       {"TZOFFSETFROM", __cal_vcalendar_parse_vtimezone_std_tzoffsetfrom },
+       {"TZOFFSETTO", __cal_vcalendar_parse_vtimezone_std_tzoffsetto }
+};
+
+char *_cal_vcalendar_parse_standard(calendar_record_h timezone, void *data)
+{
+       DBG("[%s]", __func__);
+       int i;
+       char *prop = NULL, *cont = NULL;
+       char *cursor = (char *)data;
+
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont))) {
+               if (!strncmp(prop, "END", strlen("END"))) {
+                       break;
+               }
+
+               for (i = 0; i < VTIMEZONE_STD_MAX; i++)
+               {
+                       if (!strncmp(prop, _vtimezone_std[i].prop, strlen(_vtimezone_std[i].prop))) {
+                               _vtimezone_std[i].func(timezone, cont);
+                               break;
+                       }
+               }
+
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+       }
+
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       return cursor;
+}
+
+enum {
+       VTIMEZONE_DST_DTSTART = 0x0,
+       VTIMEZONE_DST_TZOFFSETFROM,
+       VTIMEZONE_DST_TZOFFSETTO,
+       VTIMEZONE_DST_MAX,
+};
+
+static int __cal_vcalendar_parse_vtimezone_dst_dtstart(calendar_record_h timezone, void *data)
+{
+       int y, mon, d, h, min, s;
+       int nth = 0, wday = 0;
+       long long int utime;
+       char t, z;
+       char *p = (char *)data;
+
+       if (NULL == timezone)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       sscanf(p +1, "%04d%02d%02d%c%02d%02d%02d%c", &y, &mon, &d, &t, &h, &min, &s, &z);
+       utime = _cal_time_convert_itol(NULL, y, mon, d, h, min, s);
+       _cal_time_ltoi2(NULL, utime, &nth, &wday);
+       DBG("timezone daylight(%04d-%02d-%02d %02d:%02d:%02d", y, mon, d, h, min, s);
+       DBG("timezone daylight day of week(%dth/%d)", nth, wday);
+       _cal_record_set_int(timezone, _calendar_timezone.day_light_start_month, mon);
+       _cal_record_set_int(timezone, _calendar_timezone.day_light_start_position_of_week, nth);
+       _cal_record_set_int(timezone, _calendar_timezone.day_light_start_day, wday);
+       _cal_record_set_int(timezone, _calendar_timezone.day_light_start_hour, h);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_vcalendar_parse_vtimezone_dst_tzoffsetfrom(calendar_record_h timezone, void *data)
+{
+       return 0;
+}
+
+static int __cal_vcalendar_parse_vtimezone_dst_tzoffsetto(calendar_record_h timezone, void *data)
+{
+       int h, m;
+       char *p = (char *)data;
+       char c;
+       cal_timezone_s *tz = (cal_timezone_s *)timezone;
+
+       if (NULL == timezone)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       sscanf(p +1, "%c%02d%02d", &c, &h, &m);
+       DBG("timezone offsetto(%c)(%02d)(%02d)", c, h, m);
+       if (c == '-')
+       {
+               h *= -1;
+       }
+       _cal_record_set_int(timezone, _calendar_timezone.day_light_bias,
+                       (h * 60 + m) - tz->tz_offset_from_gmt);
+       return CALENDAR_ERROR_NONE;
+}
+
+struct _record_func _vtimezone_dst[VTIMEZONE_STD_MAX] =
+{
+       {"DTSTART", __cal_vcalendar_parse_vtimezone_dst_dtstart },
+       {"TZOFFSETFROM", __cal_vcalendar_parse_vtimezone_dst_tzoffsetfrom },
+       {"TZOFFSETTO", __cal_vcalendar_parse_vtimezone_dst_tzoffsetto }
+};
+
+char *_cal_vcalendar_parse_daylight(calendar_record_h timezone, void *data)
+{
+       DBG("[%s]", __func__);
+       int i;
+       char *prop = NULL, *cont = NULL;
+       char *cursor = (char *)data;
+
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont))) {
+               if (!strncmp(prop, "END", strlen("END"))) {
+                       break;
+               }
+
+               for (i = 0; i < VTIMEZONE_DST_MAX; i++)
+               {
+                       if (!strncmp(prop, _vtimezone_dst[i].prop, strlen(_vtimezone_dst[i].prop))) {
+                               _vtimezone_dst[i].func(timezone, cont);
+                               break;
+                       }
+               }
+
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+       }
+
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       return cursor;
+}
+
+char *_cal_vcalendar_parse_vtimezone(int ver, calendar_list_h *list_sch, void *data)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       char *prop = NULL, *cont = NULL;
+       char *cursor = (char *)data;
+       calendar_record_h timezone = NULL;
+
+       ret = calendar_record_create(_calendar_timezone._uri, &timezone);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_record_create() failed");
+               return NULL;
+       }
+
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont)))
+       {
+               if (!strncmp(prop, "TZID", strlen("TZID")))
+               {
+                       _cal_record_set_str(timezone, _calendar_timezone.standard_name, cont +1);
+                       _cal_record_set_str(timezone, _calendar_timezone.day_light_name, cont +1);
+                       DBG("name[%s]", cont +1);
+               }
+               else if (!strncmp(prop, "BEGIN", strlen("BEGIN")))
+               {
+                       if (!strncmp(cont + 1, "STANDARD", strlen("STANDARD")))
+                       {
+                               cursor = _cal_vcalendar_parse_standard(timezone, cursor);
+                       }
+                       else if (!strncmp(cont + 1, "DAYLIGHT", strlen("DAYLIGHT")))
+                       {
+                               cursor = _cal_vcalendar_parse_daylight(timezone, cursor);
+                       }
+                       else
+                       {
+                               DBG("Error");
+                       }
+               }
+               else if (!strncmp(prop, "END", strlen("END")))
+               {
+                       if (!strncmp(cont + 1, "VTIMEZONE", strlen("VTIMEZONE")))
+                       {
+                               break;
+                       }
+                       else
+                       {
+                               DBG("Error");
+                       }
+               }
+               else
+               {
+                               DBG("Error");
+               }
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+       }
+
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       DBG("add timezone to the list");
+       calendar_list_add(*list_sch, timezone);
+
+       return cursor;
+}
+
+/*
+ * parses vcalendar and appends record to the list.
+ */
+char *_cal_vcalendar_parse_vcalendar(calendar_list_h *list, void *data)
+{
+       DBG("[%s]", __func__);
+       int ret = CALENDAR_ERROR_NONE;
+       char *prop = NULL, *cont = NULL;
+       char *cursor = (char *)data;
+       char *p = cursor;
+       calendar_list_h l = NULL;
+
+       if (NULL == list)
+       {
+               ERR("Invalid parameter: list is NULL");
+               return NULL;
+       }
+
+       ret = calendar_list_create(&l);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_list_create() failed");
+               return NULL;
+       }
+
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont))) {
+               if (prop == NULL || cont == NULL)
+               {
+                       ERR("Failed to parse");
+                       break;
+               }
+               if (!strncmp(prop, "BEGIN", strlen("BEGIN"))) {
+                       CAL_FREE(prop);
+                       CAL_FREE(cont);
+                       break;
+               }
+
+               if (!strncmp(prop, "PRODID", strlen("PRODID"))) {
+                       _basic_funcs[VCAL_PRODID].func(NULL, cont);
+
+               } else if (!strncmp(prop, "VERSION", strlen("VERSION"))) {
+                       _basic_funcs[VCAL_VERSION].func(NULL, cont);
+
+               } else {
+
+               }
+
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+               p = cursor;
+       }
+
+       cursor = p;
+       while ((cursor = _cal_vcalendar_parse_read_line(cursor, &prop, &cont))) {
+               if (prop == NULL || cont == NULL)
+               {
+                       ERR("Failed to parse");
+                       break;
+               }
+               if (!strncmp(prop, "BEGIN", strlen("BEGIN"))) {
+
+                       if (!strncmp(cont + 1, "VEVENT", strlen("VEVENT"))) {
+                               cursor = _cal_vcalendar_parse_vevent(CALENDAR_BOOK_TYPE_EVENT, &l, cursor);
+
+                       } else if (!strncmp(cont + 1, "VTODO", strlen("VTODO"))) {
+                               cursor = _cal_vcalendar_parse_vtodo(CALENDAR_BOOK_TYPE_TODO, &l, cursor);
+
+                       } else if (!strncmp(cont + 1, "VTIMEZONE", strlen("VTIMEZONE"))) {
+                               cursor = _cal_vcalendar_parse_vtimezone(CALENDAR_BOOK_TYPE_NONE, &l, cursor);
+/*
+                       } else if (!strncmp(cont + 1, "VFREEBUSY", strlen("VFREEBUSY"))) {
+*/
+                       } else {
+
+                       }
+
+               } else if (!strncmp(prop, "END:VCALENDAR", strlen("END:VCALENDAR"))) {
+                       CAL_FREE(prop);
+                       CAL_FREE(cont);
+                       break;
+               }
+
+               CAL_FREE(prop);
+               CAL_FREE(cont);
+       }
+       CAL_FREE(prop);
+       CAL_FREE(cont);
+
+       *list = l;
+
+       return cursor;
+}
+
diff --git a/common/cal_vcalendar_parse.h b/common/cal_vcalendar_parse.h
new file mode 100644 (file)
index 0000000..6bcc0f5
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_VCALENDAR_PARSE_H__
+#define __CALENDAR_SVC_VCALENDAR_PARSE_H__
+
+#include "calendar_vcalendar.h"
+
+char *_cal_vcalendar_parse_remove_space(char *src);
+int _cal_vcalendar_parse_unfolding(char *stream);
+char *_cal_vcalendar_parse_read_line(char *stream, char **prop, char **cont);
+char *_cal_vcalendar_parse_vcalendar(calendar_list_h *list_sch, void *data);
+
+#endif // __CALENDAR_SVC_VCALENDAR_PARSE_H__
diff --git a/common/cal_view.c b/common/cal_view.c
new file mode 100644 (file)
index 0000000..8b237bc
--- /dev/null
@@ -0,0 +1,1095 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_mutex.h"
+
+// !! TODO : please check ids number
+API const _calendar_book_property_ids   _calendar_book =
+{
+        ._uri = CALENDAR_VIEW_CALENDAR,
+               .id = CAL_PROPERTY_CALENDAR_ID,
+               .uid = CAL_PROPERTY_CALENDAR_UID,
+               .name = CAL_PROPERTY_CALENDAR_NAME,
+               .description = CAL_PROPERTY_CALENDAR_DESCRIPTION,
+               .color = CAL_PROPERTY_CALENDAR_COLOR,
+               .location = CAL_PROPERTY_CALENDAR_LOCATION,
+               .visibility = CAL_PROPERTY_CALENDAR_VISIBILITY,
+               .sync_event = CAL_PROPERTY_CALENDAR_SYNC_EVENT,
+               .is_deleted = CAL_PROPERTY_CALENDAR_IS_DELETED,
+               .account_id = CAL_PROPERTY_CALENDAR_ACCOUNT_ID,
+               .store_type = CAL_PROPERTY_CALENDAR_STORE_TYPE,
+               .sync_data1 = CAL_PROPERTY_CALENDAR_SYNC_DATA1,
+               .sync_data2 = CAL_PROPERTY_CALENDAR_SYNC_DATA2,
+               .sync_data3 = CAL_PROPERTY_CALENDAR_SYNC_DATA3,
+               .sync_data4 = CAL_PROPERTY_CALENDAR_SYNC_DATA4
+};
+API const _calendar_event_property_ids   _calendar_event =
+{
+        ._uri = CALENDAR_VIEW_EVENT,
+               .id = CAL_PROPERTY_EVENT_ID,
+               .calendar_book_id = CAL_PROPERTY_EVENT_CALENDAR_ID,
+               .summary = CAL_PROPERTY_EVENT_SUMMARY,
+               .description = CAL_PROPERTY_EVENT_DESCRIPTION,
+               .location = CAL_PROPERTY_EVENT_LOCATION,
+               .categories = CAL_PROPERTY_EVENT_CATEGORIES,
+               .exdate = CAL_PROPERTY_EVENT_EXDATE,
+               .event_status = CAL_PROPERTY_EVENT_EVENT_STATUS,
+               .priority = CAL_PROPERTY_EVENT_PRIORITY,
+               .timezone = CAL_PROPERTY_EVENT_TIMEZONE,
+               .person_id = CAL_PROPERTY_EVENT_CONTACT_ID,
+               .busy_status = CAL_PROPERTY_EVENT_BUSY_STATUS,
+               .sensitivity = CAL_PROPERTY_EVENT_SENSITIVITY,
+               .uid = CAL_PROPERTY_EVENT_UID,
+               .organizer_name = CAL_PROPERTY_EVENT_ORGANIZER_NAME,
+               .organizer_email = CAL_PROPERTY_EVENT_ORGANIZER_EMAIL,
+               .meeting_status = CAL_PROPERTY_EVENT_MEETING_STATUS,
+               .original_event_id = CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID,
+               .latitude = CAL_PROPERTY_EVENT_LATITUDE,
+               .longitude = CAL_PROPERTY_EVENT_LONGITUDE,
+               .email_id = CAL_PROPERTY_EVENT_EMAIL_ID,
+               .created_time = CAL_PROPERTY_EVENT_CREATED_TIME,
+               .last_modified_time = CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME,
+               .is_deleted = CAL_PROPERTY_EVENT_IS_DELETED,
+               //CAL_PROPERTY_EVENT_HAS_RRULE,
+               .freq = CAL_PROPERTY_EVENT_FREQ,
+               .range_type = CAL_PROPERTY_EVENT_RANGE_TYPE,
+               .until_time = CAL_PROPERTY_EVENT_UNTIL,
+               .count = CAL_PROPERTY_EVENT_COUNT,
+               .interval = CAL_PROPERTY_EVENT_INTERVAL,
+               .bysecond = CAL_PROPERTY_EVENT_BYSECOND,
+               .byminute = CAL_PROPERTY_EVENT_BYMINUTE,
+               .byhour = CAL_PROPERTY_EVENT_BYHOUR,
+               .byday = CAL_PROPERTY_EVENT_BYDAY,
+               .bymonthday = CAL_PROPERTY_EVENT_BYMONTHDAY,
+               .byyearday = CAL_PROPERTY_EVENT_BYYEARDAY,
+               .byweekno = CAL_PROPERTY_EVENT_BYWEEKNO,
+               .bymonth = CAL_PROPERTY_EVENT_BYMONTH,
+               .bysetpos = CAL_PROPERTY_EVENT_BYSETPOS,
+               .wkst = CAL_PROPERTY_EVENT_WKST,
+               .recurrence_id = CAL_PROPERTY_EVENT_RECURRENCE_ID,
+               .rdate = CAL_PROPERTY_EVENT_RDATE,
+               .has_attendee = CAL_PROPERTY_EVENT_HAS_ATTENDEE,
+               .has_alarm = CAL_PROPERTY_EVENT_HAS_ALARM,
+               .calendar_system_type = CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE,
+               .sync_data1 = CAL_PROPERTY_EVENT_SYNC_DATA1,
+               .sync_data2 = CAL_PROPERTY_EVENT_SYNC_DATA2,
+               .sync_data3 = CAL_PROPERTY_EVENT_SYNC_DATA3,
+               .sync_data4 = CAL_PROPERTY_EVENT_SYNC_DATA4,
+               .start_time = CAL_PROPERTY_EVENT_START,
+               .start_tzid = CAL_PROPERTY_EVENT_START_TZID,
+               .end_time = CAL_PROPERTY_EVENT_END,
+               .end_tzid = CAL_PROPERTY_EVENT_END_TZID,
+               .calendar_alarm = CAL_PROPERTY_EVENT_CALENDAR_ALARM,
+               .calendar_attendee = CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE,
+        .exception = CAL_PROPERTY_EVENT_EXCEPTION,
+        .extended = CAL_PROPERTY_EVENT_EXTENDED,
+        .is_allday = CAL_PROPERTY_EVENT_IS_ALLDAY
+};
+API const _calendar_todo_property_ids   _calendar_todo =
+{
+        ._uri = CALENDAR_VIEW_TODO,
+        .id = CAL_PROPERTY_TODO_ID,
+        .calendar_book_id = CAL_PROPERTY_TODO_CALENDAR_ID,
+        .summary = CAL_PROPERTY_TODO_SUMMARY,
+        .description = CAL_PROPERTY_TODO_DESCRIPTION,
+        .location = CAL_PROPERTY_TODO_LOCATION,
+        .categories = CAL_PROPERTY_TODO_CATEGORIES,
+        .todo_status = CAL_PROPERTY_TODO_TODO_STATUS,
+        .priority = CAL_PROPERTY_TODO_PRIORITY,
+        .sensitivity = CAL_PROPERTY_TODO_SENSITIVITY,
+        .uid = CAL_PROPERTY_TODO_UID,
+        .latitude = CAL_PROPERTY_TODO_LATITUDE,
+        .longitude = CAL_PROPERTY_TODO_LONGITUDE,
+        .created_time = CAL_PROPERTY_TODO_CREATED_TIME,
+        .last_modified_time = CAL_PROPERTY_TODO_LAST_MODIFIED_TIME,
+        .completed_time = CAL_PROPERTY_TODO_COMPLETED_TIME,
+        .progress = CAL_PROPERTY_TODO_PROGRESS,
+        .is_deleted = CAL_PROPERTY_TODO_IS_DELETED,
+               //CAL_PROPERTY_TODO_HAS_RRULE,
+        .freq = CAL_PROPERTY_TODO_FREQ,
+        .range_type = CAL_PROPERTY_TODO_RANGE_TYPE,
+        .until_time = CAL_PROPERTY_TODO_UNTIL,
+        .count = CAL_PROPERTY_TODO_COUNT,
+        .interval = CAL_PROPERTY_TODO_INTERVAL,
+        .bysecond = CAL_PROPERTY_TODO_BYSECOND,
+        .byminute = CAL_PROPERTY_TODO_BYMINUTE,
+        .byhour = CAL_PROPERTY_TODO_BYHOUR,
+        .byday = CAL_PROPERTY_TODO_BYDAY,
+        .bymonthday = CAL_PROPERTY_TODO_BYMONTHDAY,
+        .byyearday = CAL_PROPERTY_TODO_BYYEARDAY,
+        .byweekno = CAL_PROPERTY_TODO_BYWEEKNO,
+        .bymonth = CAL_PROPERTY_TODO_BYMONTH,
+        .bysetpos = CAL_PROPERTY_TODO_BYSETPOS,
+        .wkst = CAL_PROPERTY_TODO_WKST,
+        .has_alarm = CAL_PROPERTY_TODO_HAS_ALARM,
+        .sync_data1 = CAL_PROPERTY_TODO_SYNC_DATA1,
+        .sync_data2 = CAL_PROPERTY_TODO_SYNC_DATA2,
+        .sync_data3 = CAL_PROPERTY_TODO_SYNC_DATA3,
+        .sync_data4 = CAL_PROPERTY_TODO_SYNC_DATA4,
+        .start_time = CAL_PROPERTY_TODO_START,
+        .start_tzid = CAL_PROPERTY_TODO_START_TZID,
+        .due_time = CAL_PROPERTY_TODO_DUE,
+        .due_tzid = CAL_PROPERTY_TODO_DUE_TZID,
+        .calendar_alarm = CAL_PROPERTY_TODO_CALENDAR_ALARM,
+        .organizer_name = CAL_PROPERTY_TODO_ORGANIZER_NAME,
+        .organizer_email = CAL_PROPERTY_TODO_ORGANIZER_EMAIL,
+        .has_attendee = CAL_PROPERTY_TODO_HAS_ATTENDEE,
+        .calendar_attendee = CAL_PROPERTY_TODO_CALENDAR_ATTENDEE,
+        .extended = CAL_PROPERTY_TODO_EXTENDED,
+        .is_allday = CAL_PROPERTY_TODO_IS_ALLDAY
+};
+
+API const _calendar_timezone_property_ids   _calendar_timezone =
+{
+        ._uri = CALENDAR_VIEW_TIMEZONE,
+        .id = CAL_PROPERTY_TIMEZONE_ID,
+        .calendar_book_id = CAL_PROPERTY_TIMEZONE_CALENDAR_ID,
+        .tz_offset_from_gmt = CAL_PROPERTY_TIMEZONE_TZ_OFFSET_FROM_GMT,
+        .standard_name = CAL_PROPERTY_TIMEZONE_STANDARD_NAME,
+        .standard_start_month = CAL_PROPERTY_TIMEZONE_STD_START_MONTH,
+        .standard_start_position_of_week = CAL_PROPERTY_TIMEZONE_STD_START_POSITION_OF_WEEK,
+        .standard_start_day = CAL_PROPERTY_TIMEZONE_STD_START_DAY,
+        .standard_start_hour = CAL_PROPERTY_TIMEZONE_STD_START_HOUR,
+        .standard_bias = CAL_PROPERTY_TIMEZONE_STANDARD_BIAS,
+        .day_light_name = CAL_PROPERTY_TIMEZONE_DAY_LIGHT_NAME,
+        .day_light_start_month = CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_MONTH,
+        .day_light_start_position_of_week = CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_POSITION_OF_WEEK,
+        .day_light_start_day = CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_DAY,
+        .day_light_start_hour = CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_HOUR,
+        .day_light_bias = CAL_PROPERTY_TIMEZONE_DAY_LIGHT_BIAS,
+};
+API const _calendar_attendee_property_ids   _calendar_attendee =
+{
+        ._uri = CALENDAR_VIEW_ATTENDEE,
+        .event_id = CAL_PROPERTY_ATTENDEE_EVENT_ID,
+        .number = CAL_PROPERTY_ATTENDEE_NUMBER,
+        .type = CAL_PROPERTY_ATTENDEE_TYPE,
+        .person_id = CAL_PROPERTY_ATTENDEE_CT_INDEX,
+        .uid = CAL_PROPERTY_ATTENDEE_UID,
+        .group = CAL_PROPERTY_ATTENDEE_GROUP,
+        .email = CAL_PROPERTY_ATTENDEE_EMAIL,
+        .role = CAL_PROPERTY_ATTENDEE_ROLE,
+        .status = CAL_PROPERTY_ATTENDEE_STATUS,
+        .rsvp = CAL_PROPERTY_ATTENDEE_RSVP,
+        .delegate_uri = CAL_PROPERTY_ATTENDEE_DELEGATE_URI,
+        .delegator_uri = CAL_PROPERTY_ATTENDEE_DELEGATOR_URI,
+        .name = CAL_PROPERTY_ATTENDEE_NAME
+};
+API const _calendar_alarm_property_ids   _calendar_alarm =
+{
+        ._uri = CALENDAR_VIEW_ALARM,
+        .event_id = CAL_PROPERTY_ALARM_EVENT_TODO_ID,
+        .todo_id = CAL_PROPERTY_ALARM_EVENT_TODO_ID,
+        .type = CAL_PROPERTY_ALARM_TYPE,
+        .time = CAL_PROPERTY_ALARM_TIME,
+        .tick = CAL_PROPERTY_ALARM_TICK,
+        .tick_unit = CAL_PROPERTY_ALARM_TICK_UNIT,
+        .tone = CAL_PROPERTY_ALARM_TONE,
+        .description = CAL_PROPERTY_ALARM_DESCRIPTION,
+        .alarm_id = CAL_PROPERTY_ALARM_ID
+};
+API const _calendar_instance_normal_property_ids   _calendar_instance_normal =
+{
+        ._uri = CALENDAR_VIEW_INSTANCE_NORMAL,
+        .event_id = CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID,
+        .start_time = CAL_PROPERTY_INSTANCE_NORMAL_START,
+        .end_time = CAL_PROPERTY_INSTANCE_NORMAL_END,
+        .summary = CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY,
+        .location = CAL_PROPERTY_INSTANCE_NORMAL_LOCATION,
+        .calendar_book_id = CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID,
+        .description = CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION,
+        .busy_status = CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS,
+        .event_status = CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS,
+        .priority = CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY,
+        .sensitivity = CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY,
+        .has_rrule = CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE,
+        .latitude = CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE,
+        .longitude = CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE,
+        .has_alarm = CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM,
+        .original_event_id = CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID,
+        .last_modified_time = CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME
+};
+API const _calendar_instance_allday_property_ids   _calendar_instance_allday =
+{
+        ._uri = CALENDAR_VIEW_INSTANCE_ALLDAY,
+        .event_id = CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID,
+        .start_time = CAL_PROPERTY_INSTANCE_ALLDAY_START,
+        .end_time = CAL_PROPERTY_INSTANCE_ALLDAY_END,
+        .summary = CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY,
+        .location = CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION,
+        .calendar_book_id = CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID,
+        .description = CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION,
+        .busy_status = CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS,
+        .event_status = CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS,
+        .priority = CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY,
+        .sensitivity = CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY,
+        .has_rrule = CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE,
+        .latitude = CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE,
+        .longitude = CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE,
+        .has_alarm = CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM,
+        .original_event_id = CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID,
+        .last_modified_time = CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME
+};
+API const _calendar_updated_info_property_ids   _calendar_updated_info =
+{
+        ._uri = CALENDAR_VIEW_UPDATED_INFO,
+        .id = CAL_PROPERTY_UPDATED_INFO_ID,
+        .calendar_book_id = CAL_PROPERTY_UPDATED_INFO_CALENDAR_ID,
+        .modified_status = CAL_PROPERTY_UPDATED_INFO_TYPE,
+        .version = CAL_PROPERTY_UPDATED_INFO_VERSION
+};
+
+API const _calendar_event_calendar_book_property_ids   _calendar_event_calendar_book =
+{
+        ._uri = CALENDAR_VIEW_EVENT_CALENDAR,
+        .event_id = CAL_PROPERTY_EVENT_ID,
+        .calendar_book_id = CAL_PROPERTY_EVENT_CALENDAR_ID,
+        .summary = CAL_PROPERTY_EVENT_SUMMARY,
+        .description = CAL_PROPERTY_EVENT_DESCRIPTION,
+        .location = CAL_PROPERTY_EVENT_LOCATION,
+        .categories = CAL_PROPERTY_EVENT_CATEGORIES,
+        .exdate = CAL_PROPERTY_EVENT_EXDATE,
+        .event_status = CAL_PROPERTY_EVENT_EVENT_STATUS,
+        .priority = CAL_PROPERTY_EVENT_PRIORITY,
+        .timezone = CAL_PROPERTY_EVENT_TIMEZONE,
+        .person_id = CAL_PROPERTY_EVENT_CONTACT_ID,
+        .busy_status = CAL_PROPERTY_EVENT_BUSY_STATUS,
+        .sensitivity = CAL_PROPERTY_EVENT_SENSITIVITY,
+        .uid = CAL_PROPERTY_EVENT_UID,
+        .organizer_name = CAL_PROPERTY_EVENT_ORGANIZER_NAME,
+        .organizer_email = CAL_PROPERTY_EVENT_ORGANIZER_EMAIL,
+        .meeting_status = CAL_PROPERTY_EVENT_MEETING_STATUS,
+        .original_event_id = CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID,
+        .latitude = CAL_PROPERTY_EVENT_LATITUDE,
+        .longitude = CAL_PROPERTY_EVENT_LONGITUDE,
+        .email_id = CAL_PROPERTY_EVENT_EMAIL_ID,
+        .created_time = CAL_PROPERTY_EVENT_CREATED_TIME,
+        .last_modified_time = CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME,
+        .is_deleted = CAL_PROPERTY_EVENT_IS_DELETED,
+        //CAL_PROPERTY_EVENT_HAS_RRULE,
+        .freq = CAL_PROPERTY_EVENT_FREQ,
+        .range_type = CAL_PROPERTY_EVENT_RANGE_TYPE,
+        .until_time = CAL_PROPERTY_EVENT_UNTIL,
+        .count = CAL_PROPERTY_EVENT_COUNT,
+        .interval = CAL_PROPERTY_EVENT_INTERVAL,
+        .bysecond = CAL_PROPERTY_EVENT_BYSECOND,
+        .byminute = CAL_PROPERTY_EVENT_BYMINUTE,
+        .byhour = CAL_PROPERTY_EVENT_BYHOUR,
+        .byday = CAL_PROPERTY_EVENT_BYDAY,
+        .bymonthday = CAL_PROPERTY_EVENT_BYMONTHDAY,
+        .byyearday = CAL_PROPERTY_EVENT_BYYEARDAY,
+        .byweekno = CAL_PROPERTY_EVENT_BYWEEKNO,
+        .bymonth = CAL_PROPERTY_EVENT_BYMONTH,
+        .bysetpos = CAL_PROPERTY_EVENT_BYSETPOS,
+        .wkst = CAL_PROPERTY_EVENT_WKST,
+        .recurrence_id = CAL_PROPERTY_EVENT_RECURRENCE_ID,
+        .rdate = CAL_PROPERTY_EVENT_RDATE,
+        .has_attendee = CAL_PROPERTY_EVENT_HAS_ATTENDEE,
+        .has_alarm = CAL_PROPERTY_EVENT_HAS_ALARM,
+        .calendar_system_type = CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE,
+        .sync_data1 = CAL_PROPERTY_EVENT_SYNC_DATA1,
+        .sync_data2 = CAL_PROPERTY_EVENT_SYNC_DATA2,
+        .sync_data3 = CAL_PROPERTY_EVENT_SYNC_DATA3,
+        .sync_data4 = CAL_PROPERTY_EVENT_SYNC_DATA4,
+        .start_time = CAL_PROPERTY_EVENT_START,
+        .start_tzid = CAL_PROPERTY_EVENT_START_TZID,
+        .end_time = CAL_PROPERTY_EVENT_END,
+        .end_tzid = CAL_PROPERTY_EVENT_END_TZID,
+        .is_allday = CAL_PROPERTY_EVENT_IS_ALLDAY,
+        .calendar_book_visibility = CAL_PROPERTY_CALENDAR_VISIBILITY | CAL_PROPERTY_FLAGS_FILTER,
+        .calendar_book_account_id = CAL_PROPERTY_CALENDAR_ACCOUNT_ID | CAL_PROPERTY_FLAGS_FILTER,
+};
+
+API const _calendar_todo_calendar_book_property_ids   _calendar_todo_calendar_book =
+{
+        ._uri = CALENDAR_VIEW_TODO_CALENDAR,
+        .todo_id = CAL_PROPERTY_TODO_ID,
+        .calendar_book_id = CAL_PROPERTY_TODO_CALENDAR_ID,
+        .summary = CAL_PROPERTY_TODO_SUMMARY,
+        .description = CAL_PROPERTY_TODO_DESCRIPTION,
+        .location = CAL_PROPERTY_TODO_LOCATION,
+        .categories = CAL_PROPERTY_TODO_CATEGORIES,
+        .todo_status = CAL_PROPERTY_TODO_TODO_STATUS,
+        .priority = CAL_PROPERTY_TODO_PRIORITY,
+        .sensitivity = CAL_PROPERTY_TODO_SENSITIVITY,
+        .uid = CAL_PROPERTY_TODO_UID,
+        .latitude = CAL_PROPERTY_TODO_LATITUDE,
+        .longitude = CAL_PROPERTY_TODO_LONGITUDE,
+        .created_time = CAL_PROPERTY_TODO_CREATED_TIME,
+        .last_modified_time = CAL_PROPERTY_TODO_LAST_MODIFIED_TIME,
+        .completed_time = CAL_PROPERTY_TODO_COMPLETED_TIME,
+        .progress = CAL_PROPERTY_TODO_PROGRESS,
+        .is_deleted = CAL_PROPERTY_TODO_IS_DELETED,
+        //CAL_PROPERTY_TODO_HAS_RRULE,
+        .freq = CAL_PROPERTY_TODO_FREQ,
+        .range_type = CAL_PROPERTY_TODO_RANGE_TYPE,
+        .until_time = CAL_PROPERTY_TODO_UNTIL,
+        .count = CAL_PROPERTY_TODO_COUNT,
+        .interval = CAL_PROPERTY_TODO_INTERVAL,
+        .bysecond = CAL_PROPERTY_TODO_BYSECOND,
+        .byminute = CAL_PROPERTY_TODO_BYMINUTE,
+        .byhour = CAL_PROPERTY_TODO_BYHOUR,
+        .byday = CAL_PROPERTY_TODO_BYDAY,
+        .bymonthday = CAL_PROPERTY_TODO_BYMONTHDAY,
+        .byyearday = CAL_PROPERTY_TODO_BYYEARDAY,
+        .byweekno = CAL_PROPERTY_TODO_BYWEEKNO,
+        .bymonth = CAL_PROPERTY_TODO_BYMONTH,
+        .bysetpos = CAL_PROPERTY_TODO_BYSETPOS,
+        .wkst = CAL_PROPERTY_TODO_WKST,
+        .has_alarm = CAL_PROPERTY_TODO_HAS_ALARM,
+        .sync_data1 = CAL_PROPERTY_TODO_SYNC_DATA1,
+        .sync_data2 = CAL_PROPERTY_TODO_SYNC_DATA2,
+        .sync_data3 = CAL_PROPERTY_TODO_SYNC_DATA3,
+        .sync_data4 = CAL_PROPERTY_TODO_SYNC_DATA4,
+        .start_time = CAL_PROPERTY_TODO_START,
+        .start_tzid = CAL_PROPERTY_TODO_START_TZID,
+        .due_time = CAL_PROPERTY_TODO_DUE,
+        .due_tzid = CAL_PROPERTY_TODO_DUE_TZID,
+        .organizer_name = CAL_PROPERTY_TODO_ORGANIZER_NAME,
+        .organizer_email = CAL_PROPERTY_TODO_ORGANIZER_EMAIL,
+        .has_attendee = CAL_PROPERTY_TODO_HAS_ATTENDEE,
+        .is_allday = CAL_PROPERTY_TODO_IS_ALLDAY,
+        .calendar_book_visibility = CAL_PROPERTY_CALENDAR_VISIBILITY | CAL_PROPERTY_FLAGS_FILTER,
+        .calendar_book_account_id = CAL_PROPERTY_CALENDAR_ACCOUNT_ID | CAL_PROPERTY_FLAGS_FILTER,
+};
+
+API const _calendar_event_calendar_book_attendee_property_ids   _calendar_event_calendar_book_attendee =
+{
+        ._uri = CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE,
+        .event_id = CAL_PROPERTY_EVENT_ID,
+        .calendar_book_id = CAL_PROPERTY_EVENT_CALENDAR_ID,
+        .summary = CAL_PROPERTY_EVENT_SUMMARY,
+        .description = CAL_PROPERTY_EVENT_DESCRIPTION,
+        .location = CAL_PROPERTY_EVENT_LOCATION,
+        .categories = CAL_PROPERTY_EVENT_CATEGORIES,
+        .exdate = CAL_PROPERTY_EVENT_EXDATE,
+        .event_status = CAL_PROPERTY_EVENT_EVENT_STATUS,
+        .priority = CAL_PROPERTY_EVENT_PRIORITY,
+        .timezone = CAL_PROPERTY_EVENT_TIMEZONE,
+        .person_id = CAL_PROPERTY_EVENT_CONTACT_ID,
+        .busy_status = CAL_PROPERTY_EVENT_BUSY_STATUS,
+        .sensitivity = CAL_PROPERTY_EVENT_SENSITIVITY,
+        .uid = CAL_PROPERTY_EVENT_UID,
+        .organizer_name = CAL_PROPERTY_EVENT_ORGANIZER_NAME,
+        .organizer_email = CAL_PROPERTY_EVENT_ORGANIZER_EMAIL,
+        .meeting_status = CAL_PROPERTY_EVENT_MEETING_STATUS,
+        .original_event_id = CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID,
+        .latitude = CAL_PROPERTY_EVENT_LATITUDE,
+        .longitude = CAL_PROPERTY_EVENT_LONGITUDE,
+        .email_id = CAL_PROPERTY_EVENT_EMAIL_ID,
+        .created_time = CAL_PROPERTY_EVENT_CREATED_TIME,
+        .last_modified_time = CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME,
+        .is_deleted = CAL_PROPERTY_EVENT_IS_DELETED,
+        //CAL_PROPERTY_EVENT_HAS_RRULE,
+        .freq = CAL_PROPERTY_EVENT_FREQ,
+        .range_type = CAL_PROPERTY_EVENT_RANGE_TYPE,
+        .until_time = CAL_PROPERTY_EVENT_UNTIL,
+        .count = CAL_PROPERTY_EVENT_COUNT,
+        .interval = CAL_PROPERTY_EVENT_INTERVAL,
+        .bysecond = CAL_PROPERTY_EVENT_BYSECOND,
+        .byminute = CAL_PROPERTY_EVENT_BYMINUTE,
+        .byhour = CAL_PROPERTY_EVENT_BYHOUR,
+        .byday = CAL_PROPERTY_EVENT_BYDAY,
+        .bymonthday = CAL_PROPERTY_EVENT_BYMONTHDAY,
+        .byyearday = CAL_PROPERTY_EVENT_BYYEARDAY,
+        .byweekno = CAL_PROPERTY_EVENT_BYWEEKNO,
+        .bymonth = CAL_PROPERTY_EVENT_BYMONTH,
+        .bysetpos = CAL_PROPERTY_EVENT_BYSETPOS,
+        .wkst = CAL_PROPERTY_EVENT_WKST,
+        .recurrence_id = CAL_PROPERTY_EVENT_RECURRENCE_ID,
+        .rdate = CAL_PROPERTY_EVENT_RDATE,
+        .has_attendee = CAL_PROPERTY_EVENT_HAS_ATTENDEE,
+        .has_alarm = CAL_PROPERTY_EVENT_HAS_ALARM,
+        .calendar_system_type = CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE,
+        .sync_data1 = CAL_PROPERTY_EVENT_SYNC_DATA1,
+        .sync_data2 = CAL_PROPERTY_EVENT_SYNC_DATA2,
+        .sync_data3 = CAL_PROPERTY_EVENT_SYNC_DATA3,
+        .sync_data4 = CAL_PROPERTY_EVENT_SYNC_DATA4,
+        .start_time = CAL_PROPERTY_EVENT_START,
+        .start_tzid = CAL_PROPERTY_EVENT_START_TZID,
+        .end_time = CAL_PROPERTY_EVENT_END,
+        .end_tzid = CAL_PROPERTY_EVENT_END_TZID,
+        .is_allday = CAL_PROPERTY_EVENT_IS_ALLDAY,
+        .calendar_book_visibility = CAL_PROPERTY_CALENDAR_VISIBILITY | CAL_PROPERTY_FLAGS_FILTER,
+        .calendar_book_account_id = CAL_PROPERTY_CALENDAR_ACCOUNT_ID | CAL_PROPERTY_FLAGS_FILTER,
+        .attendee_email = CAL_PROPERTY_ATTENDEE_EMAIL | CAL_PROPERTY_FLAGS_FILTER,
+        .attendee_name = CAL_PROPERTY_ATTENDEE_NAME | CAL_PROPERTY_FLAGS_FILTER
+};
+
+API const _calendar_instance_normal_calendar_book_property_ids   _calendar_instance_normal_calendar_book =
+{
+        ._uri = CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR,
+        .event_id = CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID,
+        .start_time = CAL_PROPERTY_INSTANCE_NORMAL_START,
+        .end_time = CAL_PROPERTY_INSTANCE_NORMAL_END,
+        .summary = CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY,
+        .location = CAL_PROPERTY_INSTANCE_NORMAL_LOCATION,
+        .calendar_book_id = CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID,
+        .description = CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION,
+        .busy_status = CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS,
+        .event_status = CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS,
+        .priority = CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY,
+        .sensitivity = CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY,
+        .has_rrule = CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE,
+        .latitude = CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE,
+        .longitude = CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE,
+        .has_alarm = CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM,
+        .original_event_id = CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID,
+        .calendar_book_visibility = CAL_PROPERTY_CALENDAR_VISIBILITY | CAL_PROPERTY_FLAGS_FILTER,
+        .calendar_book_account_id = CAL_PROPERTY_CALENDAR_ACCOUNT_ID | CAL_PROPERTY_FLAGS_FILTER,
+        .last_modified_time = CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME
+};
+
+API const _calendar_instance_allday_calendar_book_property_ids   _calendar_instance_allday_calendar_book =
+{
+        ._uri = CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR,
+        .event_id = CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID,
+        .start_time = CAL_PROPERTY_INSTANCE_ALLDAY_START,
+        .end_time = CAL_PROPERTY_INSTANCE_ALLDAY_END,
+        .summary = CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY,
+        .location = CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION,
+        .calendar_book_id = CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID,
+        .description = CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION,
+        .busy_status = CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS,
+        .event_status = CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS,
+        .priority = CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY,
+        .sensitivity = CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY,
+        .has_rrule = CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE,
+        .latitude = CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE,
+        .longitude = CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE,
+        .has_alarm = CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM,
+        .original_event_id = CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID,
+        .calendar_book_visibility = CAL_PROPERTY_CALENDAR_VISIBILITY | CAL_PROPERTY_FLAGS_FILTER,
+        .calendar_book_account_id = CAL_PROPERTY_CALENDAR_ACCOUNT_ID | CAL_PROPERTY_FLAGS_FILTER,
+        .last_modified_time = CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME
+};
+
+API const _calendar_extended_property_property_ids   _calendar_extended_property =
+{
+        ._uri = CALENDAR_VIEW_EXTENDED,
+        .id = CAL_PROPERTY_EXTENDED_ID,
+        .record_id = CAL_PROPERTY_EXTENDED_RECORD_ID,
+        .record_type = CAL_PROPERTY_EXTENDED_RECORD_TYPE,
+        .key = CAL_PROPERTY_EXTENDED_KEY,
+        .value = CAL_PROPERTY_EXTENDED_VALUE
+};
+
+//////////////////////
+// cal_property_info_s
+
+const cal_property_info_s  __property_calendar_book[] = {
+        {CAL_PROPERTY_CALENDAR_ID           ,       "id"},
+        {CAL_PROPERTY_CALENDAR_UID          ,       "uid"},
+        {CAL_PROPERTY_CALENDAR_NAME         ,       "name"},
+        {CAL_PROPERTY_CALENDAR_DESCRIPTION  ,       "description"},
+        {CAL_PROPERTY_CALENDAR_COLOR        ,       "color"},
+        {CAL_PROPERTY_CALENDAR_LOCATION     ,       "location"},
+        {CAL_PROPERTY_CALENDAR_VISIBILITY   ,       "visibility"},
+        {CAL_PROPERTY_CALENDAR_SYNC_EVENT   ,       "sync_event"},
+        {CAL_PROPERTY_CALENDAR_IS_DELETED   ,       "is_deleted"},
+        {CAL_PROPERTY_CALENDAR_ACCOUNT_ID   ,       "account_id"},
+        {CAL_PROPERTY_CALENDAR_STORE_TYPE   ,       "store_type"},
+        {CAL_PROPERTY_CALENDAR_SYNC_DATA1   ,       "sync_data1"},
+        {CAL_PROPERTY_CALENDAR_SYNC_DATA2   ,       "sync_data2"},
+        {CAL_PROPERTY_CALENDAR_SYNC_DATA3   ,       "sync_data3"},
+        {CAL_PROPERTY_CALENDAR_SYNC_DATA4   ,       "sync_data4"},
+};
+
+const cal_property_info_s   __property_event[] =
+{
+        {CAL_PROPERTY_EVENT_ID,                     "id"},
+        {CAL_PROPERTY_EVENT_CALENDAR_ID,            "calendar_id"},
+        {CAL_PROPERTY_EVENT_SUMMARY,                "summary"},
+        {CAL_PROPERTY_EVENT_DESCRIPTION,            "description"},
+        {CAL_PROPERTY_EVENT_LOCATION,               "location"},
+        {CAL_PROPERTY_EVENT_CATEGORIES,             "categories"},
+        {CAL_PROPERTY_EVENT_EXDATE,                 "exdate"},
+        {CAL_PROPERTY_EVENT_EVENT_STATUS,           "task_status"},
+        {CAL_PROPERTY_EVENT_PRIORITY,               "priority"},
+        {CAL_PROPERTY_EVENT_TIMEZONE,               "timezone"},
+        {CAL_PROPERTY_EVENT_CONTACT_ID,             "contact_id"},
+        {CAL_PROPERTY_EVENT_BUSY_STATUS,            "busy_status"},
+        {CAL_PROPERTY_EVENT_SENSITIVITY,            "sensitivity"},
+        {CAL_PROPERTY_EVENT_UID,                    "uid"},
+        {CAL_PROPERTY_EVENT_ORGANIZER_NAME,         "organizer_name"},
+        {CAL_PROPERTY_EVENT_ORGANIZER_EMAIL,        "organizer_email"},
+        {CAL_PROPERTY_EVENT_MEETING_STATUS,         "meeting_status"},
+        {CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID,      "original_event_id"},
+        {CAL_PROPERTY_EVENT_LATITUDE,               "latitude"},
+        {CAL_PROPERTY_EVENT_LONGITUDE,              "longitude"},
+        {CAL_PROPERTY_EVENT_EMAIL_ID,               "email_id"},
+        {CAL_PROPERTY_EVENT_CREATED_TIME,           "created_time"},
+        {CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME,     "last_mod"},
+        {CAL_PROPERTY_EVENT_IS_DELETED,             "is_deleted"},
+        {CAL_PROPERTY_EVENT_FREQ,                   "freq"},
+        {CAL_PROPERTY_EVENT_RANGE_TYPE,             "range_type"},
+        {CAL_PROPERTY_EVENT_UNTIL,                  "until_type, until_utime, until_datetime"},
+        {CAL_PROPERTY_EVENT_COUNT,                  "count"},
+        {CAL_PROPERTY_EVENT_INTERVAL,               "interval"},
+        {CAL_PROPERTY_EVENT_BYSECOND,               "bysecond"},
+        {CAL_PROPERTY_EVENT_BYMINUTE,               "byminute"},
+        {CAL_PROPERTY_EVENT_BYHOUR,                 "byhour"},
+        {CAL_PROPERTY_EVENT_BYDAY,                  "byday"},
+        {CAL_PROPERTY_EVENT_BYMONTHDAY,             "bymonthday"},
+        {CAL_PROPERTY_EVENT_BYYEARDAY,              "byyearday"},
+        {CAL_PROPERTY_EVENT_BYWEEKNO,               "byweekno"},
+        {CAL_PROPERTY_EVENT_BYMONTH,                "bymonth"},
+        {CAL_PROPERTY_EVENT_BYSETPOS,               "bysetpos"},
+        {CAL_PROPERTY_EVENT_WKST,                   "wkst"},
+        {CAL_PROPERTY_EVENT_RECURRENCE_ID,          "recurrence_id"},
+        {CAL_PROPERTY_EVENT_RDATE,                  "rdate"},
+        {CAL_PROPERTY_EVENT_HAS_ATTENDEE,           "has_attendee"},
+        {CAL_PROPERTY_EVENT_HAS_ALARM,              "has_alarm"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA1,             "sync_data1"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA2,             "sync_data2"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA3,             "sync_data3"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA4,             "sync_data4"},
+        {CAL_PROPERTY_EVENT_START,                  "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_EVENT_END,                    "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_EVENT_CALENDAR_ALARM,         NULL},
+        {CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE,      NULL},
+        {CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE,   "system_type"},
+        {CAL_PROPERTY_EVENT_START_TZID,             "dtstart_tzid"},
+        {CAL_PROPERTY_EVENT_END_TZID,               "dtend_tzid"},
+        {CAL_PROPERTY_EVENT_EXCEPTION,              NULL},
+        {CAL_PROPERTY_EVENT_EXTENDED,               NULL},
+        {CAL_PROPERTY_EVENT_IS_ALLDAY,              "dtstart_type"},
+};
+
+const cal_property_info_s   __property_todo[] =
+{
+        {CAL_PROPERTY_TODO_ID,                      "id"},
+        {CAL_PROPERTY_TODO_CALENDAR_ID,             "calendar_id"},
+        {CAL_PROPERTY_TODO_SUMMARY,                 "summary"},
+        {CAL_PROPERTY_TODO_DESCRIPTION,             "description"},
+        {CAL_PROPERTY_TODO_LOCATION,                "location"},
+        {CAL_PROPERTY_TODO_CATEGORIES,              "categories"},
+        {CAL_PROPERTY_TODO_TODO_STATUS,             "task_status"},
+        {CAL_PROPERTY_TODO_PRIORITY,                "priority"},
+        {CAL_PROPERTY_TODO_SENSITIVITY,             "sensitivity"},
+        {CAL_PROPERTY_TODO_UID,                     "uid"},
+        {CAL_PROPERTY_TODO_LATITUDE,                "latitude"},
+        {CAL_PROPERTY_TODO_LONGITUDE,               "longitude"},
+        {CAL_PROPERTY_TODO_PROGRESS,                "progress"},
+        {CAL_PROPERTY_TODO_CREATED_TIME,            "created_time"},
+        {CAL_PROPERTY_TODO_LAST_MODIFIED_TIME,      "last_mod"},
+        {CAL_PROPERTY_TODO_COMPLETED_TIME,          "completed_time"},
+        {CAL_PROPERTY_TODO_IS_DELETED,              "is_deleted"},
+        {CAL_PROPERTY_TODO_FREQ,                    "freq"},
+        {CAL_PROPERTY_TODO_RANGE_TYPE,              "range_type"},
+        {CAL_PROPERTY_TODO_UNTIL,                   "until_type, until_utime, until_datetime"},
+        {CAL_PROPERTY_TODO_COUNT,                   "count"},
+        {CAL_PROPERTY_TODO_INTERVAL,                "interval"},
+        {CAL_PROPERTY_TODO_BYSECOND,                "bysecond"},
+        {CAL_PROPERTY_TODO_BYMINUTE,                "byminute"},
+        {CAL_PROPERTY_TODO_BYHOUR,                  "byhour"},
+        {CAL_PROPERTY_TODO_BYDAY,                   "byday"},
+        {CAL_PROPERTY_TODO_BYMONTHDAY,              "bymonthday"},
+        {CAL_PROPERTY_TODO_BYYEARDAY,               "byyearday"},
+        {CAL_PROPERTY_TODO_BYWEEKNO,                "byweekno"},
+        {CAL_PROPERTY_TODO_BYMONTH,                 "bymonth"},
+        {CAL_PROPERTY_TODO_BYSETPOS,                "bysetpos"},
+        {CAL_PROPERTY_TODO_WKST,                    "wkst"},
+        {CAL_PROPERTY_TODO_HAS_ALARM,               "has_alarm"},
+        {CAL_PROPERTY_TODO_SYNC_DATA1,              "sync_data1"},
+        {CAL_PROPERTY_TODO_SYNC_DATA2,              "sync_data2"},
+        {CAL_PROPERTY_TODO_SYNC_DATA3,              "sync_data3"},
+        {CAL_PROPERTY_TODO_SYNC_DATA4,              "sync_data4"},
+        {CAL_PROPERTY_TODO_START,                   "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_TODO_DUE,                     "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_TODO_CALENDAR_ALARM,          NULL},
+        {CAL_PROPERTY_TODO_START_TZID,              "dtstart_tzid"},
+        {CAL_PROPERTY_TODO_DUE_TZID,                "dtend_tzid"},
+        {CAL_PROPERTY_TODO_ORGANIZER_NAME,          "organizer_name"},
+        {CAL_PROPERTY_TODO_ORGANIZER_EMAIL,         "organizer_email"},
+        {CAL_PROPERTY_TODO_HAS_ATTENDEE,            "has_attendee"},
+        {CAL_PROPERTY_TODO_CALENDAR_ATTENDEE,       NULL},
+        {CAL_PROPERTY_TODO_EXTENDED,                NULL},
+        {CAL_PROPERTY_TODO_IS_ALLDAY,               "dtend_type"},
+};
+
+const cal_property_info_s   __property_timezone[] =
+{
+        {CAL_PROPERTY_TIMEZONE_ID,                                  "id"},
+        {CAL_PROPERTY_TIMEZONE_TZ_OFFSET_FROM_GMT,                  "tz_offset_from_gmt"},
+        {CAL_PROPERTY_TIMEZONE_STANDARD_NAME,                       "standard_name"},
+        {CAL_PROPERTY_TIMEZONE_STD_START_MONTH,                     "std_start_month"},
+        {CAL_PROPERTY_TIMEZONE_STD_START_POSITION_OF_WEEK,          "std_start_position_of_week"},
+        {CAL_PROPERTY_TIMEZONE_STD_START_DAY,                       "std_start_day"},
+        {CAL_PROPERTY_TIMEZONE_STD_START_HOUR,                      "std_start_hour"},
+        {CAL_PROPERTY_TIMEZONE_STANDARD_BIAS,                       "standard_bias"},
+        {CAL_PROPERTY_TIMEZONE_DAY_LIGHT_NAME,                      "day_light_name"},
+        {CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_MONTH,               "day_light_start_month"},
+        {CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_POSITION_OF_WEEK,    "day_light_start_position_of_week"},
+        {CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_DAY,                 "day_light_start_day"},
+        {CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_HOUR,                "day_light_start_hour"},
+        {CAL_PROPERTY_TIMEZONE_DAY_LIGHT_BIAS,                      "day_light_bias"},
+        {CAL_PROPERTY_TIMEZONE_CALENDAR_ID,                         "calendar_id"},
+};
+
+const cal_property_info_s   __property_attendee[] =
+{
+        {CAL_PROPERTY_ATTENDEE_NUMBER,              "attendee_number"},
+        {CAL_PROPERTY_ATTENDEE_TYPE,                "attendee_type"},
+        {CAL_PROPERTY_ATTENDEE_CT_INDEX,            "attendee_ct_index"},
+        {CAL_PROPERTY_ATTENDEE_UID,                 "attendee_uid"},
+        {CAL_PROPERTY_ATTENDEE_GROUP,               "attendee_group"},
+        {CAL_PROPERTY_ATTENDEE_EMAIL,               "attendee_email"},
+        {CAL_PROPERTY_ATTENDEE_ROLE,                "attendee_role"},
+        {CAL_PROPERTY_ATTENDEE_STATUS,              "attendee_status"},
+        {CAL_PROPERTY_ATTENDEE_RSVP,                "attendee_rsvp"},
+        {CAL_PROPERTY_ATTENDEE_DELEGATE_URI,        "attendee_delegate_uri"},
+        {CAL_PROPERTY_ATTENDEE_DELEGATOR_URI,       "attendee_delegator_uri"},
+        {CAL_PROPERTY_ATTENDEE_NAME,                "attendee_name"},
+        {CAL_PROPERTY_ATTENDEE_EVENT_ID,            "event_id"},
+};
+
+const cal_property_info_s   __property_alarm[] =
+{
+        {CAL_PROPERTY_ALARM_TYPE,               "alarm_type"},
+        {CAL_PROPERTY_ALARM_TIME,               "alarm_time"},
+        {CAL_PROPERTY_ALARM_TICK,               "remind_tick"},
+        {CAL_PROPERTY_ALARM_TICK_UNIT,          "remind_tick_unit"},
+        {CAL_PROPERTY_ALARM_TONE,               "alarm_tone"},
+        {CAL_PROPERTY_ALARM_DESCRIPTION,        "alarm_description"},
+        {CAL_PROPERTY_ALARM_ID,                 "alarm_id"},
+        {CAL_PROPERTY_ALARM_EVENT_TODO_ID,      "event_id"},
+};
+
+const cal_property_info_s   __property_instance_normal[] =
+{
+        {CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID,             "event_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_START,                "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_END,                  "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY,              "summary"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LOCATION,             "location"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID,          "calendar_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION,          "description"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS,          "busy_status"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS,         "task_status"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY,             "priority"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY,          "sensitivity"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE,            "rrule_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE,             "latitude"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE,            "longitude"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM,            "has_alarm"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID,    "original_event_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME,   "last_mod"},
+};
+
+const cal_property_info_s   __property_instance_allday[] =
+{
+        {CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID,             "event_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_START,                "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_END,                  "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY,              "summary"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION,             "location"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID,          "calendar_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION,          "description"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS,          "busy_status"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS,         "task_status"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY,             "priority"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY,          "sensitivity"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE,             "rrule_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE,             "latitude"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE,            "longitude"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM,            "has_alarm"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID,    "original_event_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME,    "last_mod"},
+};
+
+const cal_property_info_s   __property_updated_info[] =
+{
+        {CAL_PROPERTY_UPDATED_INFO_ID,                  "id"},
+        {CAL_PROPERTY_UPDATED_INFO_CALENDAR_ID,         "calendar_id"},
+        {CAL_PROPERTY_UPDATED_INFO_TYPE,                "type"},
+        {CAL_PROPERTY_UPDATED_INFO_VERSION,             "ver"},
+};
+
+const cal_property_info_s   __property_search_event_calendar[] =
+{
+        {CAL_PROPERTY_EVENT_ID,                     "id"},
+        {CAL_PROPERTY_EVENT_CALENDAR_ID,            "calendar_id"},
+        {CAL_PROPERTY_EVENT_SUMMARY,                "summary"},
+        {CAL_PROPERTY_EVENT_DESCRIPTION,            "description"},
+        {CAL_PROPERTY_EVENT_LOCATION,               "location"},
+        {CAL_PROPERTY_EVENT_CATEGORIES,             "categories"},
+        {CAL_PROPERTY_EVENT_EXDATE,                 "exdate"},
+        {CAL_PROPERTY_EVENT_EVENT_STATUS,           "task_status"},
+        {CAL_PROPERTY_EVENT_PRIORITY,               "priority"},
+        {CAL_PROPERTY_EVENT_TIMEZONE,               "timezone"},
+        {CAL_PROPERTY_EVENT_CONTACT_ID,             "contact_id"},
+        {CAL_PROPERTY_EVENT_BUSY_STATUS,            "busy_status"},
+        {CAL_PROPERTY_EVENT_SENSITIVITY,            "sensitivity"},
+        {CAL_PROPERTY_EVENT_UID,                    "uid"},
+        {CAL_PROPERTY_EVENT_ORGANIZER_NAME,         "organizer_name"},
+        {CAL_PROPERTY_EVENT_ORGANIZER_EMAIL,        "organizer_email"},
+        {CAL_PROPERTY_EVENT_MEETING_STATUS,         "meeting_status"},
+        {CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID,      "original_event_id"},
+        {CAL_PROPERTY_EVENT_LATITUDE,               "latitude"},
+        {CAL_PROPERTY_EVENT_LONGITUDE,              "longitude"},
+        {CAL_PROPERTY_EVENT_EMAIL_ID,               "email_id"},
+        {CAL_PROPERTY_EVENT_CREATED_TIME,           "created_time"},
+        {CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME,     "last_mod"},
+        {CAL_PROPERTY_EVENT_IS_DELETED,             "is_deleted"},
+        {CAL_PROPERTY_EVENT_FREQ,                   "freq"},
+        {CAL_PROPERTY_EVENT_RANGE_TYPE,             "range_type"},
+        {CAL_PROPERTY_EVENT_UNTIL,                  "until_type, until_utime, until_datetime"},
+        {CAL_PROPERTY_EVENT_COUNT,                  "count"},
+        {CAL_PROPERTY_EVENT_INTERVAL,               "interval"},
+        {CAL_PROPERTY_EVENT_BYSECOND,               "bysecond"},
+        {CAL_PROPERTY_EVENT_BYMINUTE,               "byminute"},
+        {CAL_PROPERTY_EVENT_BYHOUR,                 "byhour"},
+        {CAL_PROPERTY_EVENT_BYDAY,                  "byday"},
+        {CAL_PROPERTY_EVENT_BYMONTHDAY,             "bymonthday"},
+        {CAL_PROPERTY_EVENT_BYYEARDAY,              "byyearday"},
+        {CAL_PROPERTY_EVENT_BYWEEKNO,               "byweekno"},
+        {CAL_PROPERTY_EVENT_BYMONTH,                "bymonth"},
+        {CAL_PROPERTY_EVENT_BYSETPOS,               "bysetpos"},
+        {CAL_PROPERTY_EVENT_WKST,                   "wkst"},
+        {CAL_PROPERTY_EVENT_RECURRENCE_ID,          "recurrence_id"},
+        {CAL_PROPERTY_EVENT_RDATE,                  "rdate"},
+        {CAL_PROPERTY_EVENT_HAS_ATTENDEE,           "has_attendee"},
+        {CAL_PROPERTY_EVENT_HAS_ALARM,              "has_alarm"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA1,             "sync_data1"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA2,             "sync_data2"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA3,             "sync_data3"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA4,             "sync_data4"},
+        {CAL_PROPERTY_EVENT_START,                  "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_EVENT_END,                    "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE,   "system_type"},
+        {CAL_PROPERTY_EVENT_START_TZID,             "dtstart_tzid"},
+        {CAL_PROPERTY_EVENT_END_TZID,               "dtend_tzid"},
+        {CAL_PROPERTY_EVENT_IS_ALLDAY,              "dtstart_type"},
+        {(CAL_PROPERTY_CALENDAR_VISIBILITY|CAL_PROPERTY_FLAGS_FILTER)  ,       "visibility"},
+        {(CAL_PROPERTY_CALENDAR_ACCOUNT_ID|CAL_PROPERTY_FLAGS_FILTER)   ,       "account_id"},
+};
+
+const cal_property_info_s   __property_search_todo_calendar[] =
+{
+        {CAL_PROPERTY_TODO_ID,                      "id"},
+        {CAL_PROPERTY_TODO_CALENDAR_ID,             "calendar_id"},
+        {CAL_PROPERTY_TODO_SUMMARY,                 "summary"},
+        {CAL_PROPERTY_TODO_DESCRIPTION,             "description"},
+        {CAL_PROPERTY_TODO_LOCATION,                "location"},
+        {CAL_PROPERTY_TODO_CATEGORIES,              "categories"},
+        {CAL_PROPERTY_TODO_TODO_STATUS,             "task_status"},
+        {CAL_PROPERTY_TODO_PRIORITY,                "priority"},
+        {CAL_PROPERTY_TODO_SENSITIVITY,             "sensitivity"},
+        {CAL_PROPERTY_TODO_UID,                     "uid"},
+        {CAL_PROPERTY_TODO_LATITUDE,                "latitude"},
+        {CAL_PROPERTY_TODO_LONGITUDE,               "longitude"},
+        {CAL_PROPERTY_TODO_PROGRESS,                "progress"},
+        {CAL_PROPERTY_TODO_CREATED_TIME,            "created_time"},
+        {CAL_PROPERTY_TODO_LAST_MODIFIED_TIME,      "last_mod"},
+        {CAL_PROPERTY_TODO_COMPLETED_TIME,          "completed_time"},
+        {CAL_PROPERTY_TODO_IS_DELETED,              "is_deleted"},
+        {CAL_PROPERTY_TODO_FREQ,                    "freq"},
+        {CAL_PROPERTY_TODO_RANGE_TYPE,              "range_type"},
+        {CAL_PROPERTY_TODO_UNTIL,                   "until_type, until_utime, until_datetime"},
+        {CAL_PROPERTY_TODO_COUNT,                   "count"},
+        {CAL_PROPERTY_TODO_INTERVAL,                "interval"},
+        {CAL_PROPERTY_TODO_BYSECOND,                "bysecond"},
+        {CAL_PROPERTY_TODO_BYMINUTE,                "byminute"},
+        {CAL_PROPERTY_TODO_BYHOUR,                  "byhour"},
+        {CAL_PROPERTY_TODO_BYDAY,                   "byday"},
+        {CAL_PROPERTY_TODO_BYMONTHDAY,              "bymonthday"},
+        {CAL_PROPERTY_TODO_BYYEARDAY,               "byyearday"},
+        {CAL_PROPERTY_TODO_BYWEEKNO,                "byweekno"},
+        {CAL_PROPERTY_TODO_BYMONTH,                 "bymonth"},
+        {CAL_PROPERTY_TODO_BYSETPOS,                "bysetpos"},
+        {CAL_PROPERTY_TODO_WKST,                    "wkst"},
+        {CAL_PROPERTY_TODO_HAS_ALARM,               "has_alarm"},
+        {CAL_PROPERTY_TODO_SYNC_DATA1,              "sync_data1"},
+        {CAL_PROPERTY_TODO_SYNC_DATA2,              "sync_data2"},
+        {CAL_PROPERTY_TODO_SYNC_DATA3,              "sync_data3"},
+        {CAL_PROPERTY_TODO_SYNC_DATA4,              "sync_data4"},
+        {CAL_PROPERTY_TODO_START,                   "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_TODO_DUE,                     "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_TODO_START_TZID,              "dtstart_tzid"},
+        {CAL_PROPERTY_TODO_DUE_TZID,                "dtend_tzid"},
+        {CAL_PROPERTY_TODO_ORGANIZER_NAME,          "organizer_name"},
+        {CAL_PROPERTY_TODO_ORGANIZER_EMAIL,         "organizer_email"},
+        {CAL_PROPERTY_TODO_HAS_ATTENDEE,            "has_attendee"},
+        {CAL_PROPERTY_TODO_IS_ALLDAY,               "dtend_type"},
+        {(CAL_PROPERTY_CALENDAR_VISIBILITY|CAL_PROPERTY_FLAGS_FILTER)  ,       "visibility"},
+        {(CAL_PROPERTY_CALENDAR_ACCOUNT_ID|CAL_PROPERTY_FLAGS_FILTER)   ,       "account_id"},
+};
+
+const cal_property_info_s   __property_search_event_calendar_attendee[] =
+{
+        {CAL_PROPERTY_EVENT_ID,                     "id"},
+        {CAL_PROPERTY_EVENT_CALENDAR_ID,            "calendar_id"},
+        {CAL_PROPERTY_EVENT_SUMMARY,                "summary"},
+        {CAL_PROPERTY_EVENT_DESCRIPTION,            "description"},
+        {CAL_PROPERTY_EVENT_LOCATION,               "location"},
+        {CAL_PROPERTY_EVENT_CATEGORIES,             "categories"},
+        {CAL_PROPERTY_EVENT_EXDATE,                 "exdate"},
+        {CAL_PROPERTY_EVENT_EVENT_STATUS,           "task_status"},
+        {CAL_PROPERTY_EVENT_PRIORITY,               "priority"},
+        {CAL_PROPERTY_EVENT_TIMEZONE,               "timezone"},
+        {CAL_PROPERTY_EVENT_CONTACT_ID,             "contact_id"},
+        {CAL_PROPERTY_EVENT_BUSY_STATUS,            "busy_status"},
+        {CAL_PROPERTY_EVENT_SENSITIVITY,            "sensitivity"},
+        {CAL_PROPERTY_EVENT_UID,                    "uid"},
+        {CAL_PROPERTY_EVENT_ORGANIZER_NAME,         "organizer_name"},
+        {CAL_PROPERTY_EVENT_ORGANIZER_EMAIL,        "organizer_email"},
+        {CAL_PROPERTY_EVENT_MEETING_STATUS,         "meeting_status"},
+        {CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID,      "original_event_id"},
+        {CAL_PROPERTY_EVENT_LATITUDE,               "latitude"},
+        {CAL_PROPERTY_EVENT_LONGITUDE,              "longitude"},
+        {CAL_PROPERTY_EVENT_EMAIL_ID,               "email_id"},
+        {CAL_PROPERTY_EVENT_CREATED_TIME,           "created_time"},
+        {CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME,     "last_mod"},
+        {CAL_PROPERTY_EVENT_IS_DELETED,             "is_deleted"},
+        {CAL_PROPERTY_EVENT_FREQ,                   "freq"},
+        {CAL_PROPERTY_EVENT_RANGE_TYPE,             "range_type"},
+        {CAL_PROPERTY_EVENT_UNTIL,                  "until_type, until_utime, until_datetime"},
+        {CAL_PROPERTY_EVENT_COUNT,                  "count"},
+        {CAL_PROPERTY_EVENT_INTERVAL,               "interval"},
+        {CAL_PROPERTY_EVENT_BYSECOND,               "bysecond"},
+        {CAL_PROPERTY_EVENT_BYMINUTE,               "byminute"},
+        {CAL_PROPERTY_EVENT_BYHOUR,                 "byhour"},
+        {CAL_PROPERTY_EVENT_BYDAY,                  "byday"},
+        {CAL_PROPERTY_EVENT_BYMONTHDAY,             "bymonthday"},
+        {CAL_PROPERTY_EVENT_BYYEARDAY,              "byyearday"},
+        {CAL_PROPERTY_EVENT_BYWEEKNO,               "byweekno"},
+        {CAL_PROPERTY_EVENT_BYMONTH,                "bymonth"},
+        {CAL_PROPERTY_EVENT_BYSETPOS,               "bysetpos"},
+        {CAL_PROPERTY_EVENT_WKST,                   "wkst"},
+        {CAL_PROPERTY_EVENT_RECURRENCE_ID,          "recurrence_id"},
+        {CAL_PROPERTY_EVENT_RDATE,                  "rdate"},
+        {CAL_PROPERTY_EVENT_HAS_ATTENDEE,           "has_attendee"},
+        {CAL_PROPERTY_EVENT_HAS_ALARM,              "has_alarm"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA1,             "sync_data1"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA2,             "sync_data2"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA3,             "sync_data3"},
+        {CAL_PROPERTY_EVENT_SYNC_DATA4,             "sync_data4"},
+        {CAL_PROPERTY_EVENT_START,                  "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_EVENT_END,                    "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE,   "system_type"},
+        {CAL_PROPERTY_EVENT_START_TZID,             "dtstart_tzid"},
+        {CAL_PROPERTY_EVENT_END_TZID,               "dtend_tzid"},
+        {CAL_PROPERTY_EVENT_IS_ALLDAY,              "dtstart_type"},
+        {(CAL_PROPERTY_CALENDAR_VISIBILITY|CAL_PROPERTY_FLAGS_FILTER)  ,       "visibility"},
+        {(CAL_PROPERTY_CALENDAR_ACCOUNT_ID|CAL_PROPERTY_FLAGS_FILTER)   ,       "account_id"},
+        {(CAL_PROPERTY_ATTENDEE_EMAIL|CAL_PROPERTY_FLAGS_FILTER),               "attendee_email"},
+        {(CAL_PROPERTY_ATTENDEE_NAME|CAL_PROPERTY_FLAGS_FILTER),                "attendee_name"},
+};
+
+const cal_property_info_s   __property_search_instance_normal_calendar[] =
+{
+        {CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID,             "event_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_START,                "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_END,                  "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY,              "summary"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LOCATION,             "location"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID,          "calendar_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION,          "description"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS,          "busy_status"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS,         "task_status"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY,             "priority"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY,          "sensitivity"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE,             "rrule_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE,             "latitude"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE,            "longitude"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM,            "has_alarm"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID,    "original_event_id"},
+        {(CAL_PROPERTY_CALENDAR_VISIBILITY|CAL_PROPERTY_FLAGS_FILTER)  ,       "visibility"},
+        {(CAL_PROPERTY_CALENDAR_ACCOUNT_ID|CAL_PROPERTY_FLAGS_FILTER)   ,       "account_id"},
+        {CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME,   "last_mod"},
+};
+
+
+const cal_property_info_s   __property_search_instance_allday_calendar[] =
+{
+        {CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID,             "event_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_START,                "dtstart_type, dtstart_utime, dtstart_datetime"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_END,                  "dtend_type, dtend_utime, dtend_datetime"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY,              "summary"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION,             "location"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID,          "calendar_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION,          "description"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS,          "busy_status"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS,         "task_status"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY,             "priority"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY,          "sensitivity"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE,             "rrule_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE,             "latitude"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE,            "longitude"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM,            "has_alarm"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID,    "original_event_id"},
+        {(CAL_PROPERTY_CALENDAR_VISIBILITY|CAL_PROPERTY_FLAGS_FILTER)  ,       "visibility"},
+        {(CAL_PROPERTY_CALENDAR_ACCOUNT_ID|CAL_PROPERTY_FLAGS_FILTER)   ,       "account_id"},
+        {CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME,   "last_mod"},
+};
+
+const cal_property_info_s   __property_extended[] =
+{
+        {CAL_PROPERTY_EXTENDED_ID,              "id"},
+        {CAL_PROPERTY_EXTENDED_RECORD_ID,       "record_id"},
+        {CAL_PROPERTY_EXTENDED_RECORD_TYPE,     "record_type"},
+        {CAL_PROPERTY_EXTENDED_KEY,             "key"},
+        {CAL_PROPERTY_EXTENDED_VALUE,           "value"},
+};
+
+typedef struct {
+    char *view_uri;
+    cal_record_type_e type;
+    cal_property_info_s *properties;
+    int property_count;
+}cal_view_uri_info_s;
+
+#define PTR_COUNT(X)    (void*)(X), sizeof(X)/sizeof(cal_property_info_s)
+
+
+static const cal_view_uri_info_s __tables[] = {
+    {CALENDAR_VIEW_CALENDAR,        CAL_RECORD_TYPE_CALENDAR,           PTR_COUNT(__property_calendar_book) },
+    {CALENDAR_VIEW_EVENT,           CAL_RECORD_TYPE_EVENT,              PTR_COUNT(__property_event) },
+    {CALENDAR_VIEW_TODO,            CAL_RECORD_TYPE_TODO,               PTR_COUNT(__property_todo) },
+    {CALENDAR_VIEW_TIMEZONE,        CAL_RECORD_TYPE_TIMEZONE,           PTR_COUNT(__property_timezone) },
+    {CALENDAR_VIEW_ATTENDEE,        CAL_RECORD_TYPE_ATTENDEE,           PTR_COUNT(__property_attendee) },
+    {CALENDAR_VIEW_ALARM,           CAL_RECORD_TYPE_ALARM,              PTR_COUNT(__property_alarm) },
+    {CALENDAR_VIEW_INSTANCE_NORMAL, CAL_RECORD_TYPE_INSTANCE_NORMAL,    PTR_COUNT(__property_instance_normal) },
+    {CALENDAR_VIEW_INSTANCE_ALLDAY, CAL_RECORD_TYPE_INSTANCE_ALLDAY,    PTR_COUNT(__property_instance_allday) },
+    {CALENDAR_VIEW_UPDATED_INFO,    CAL_RECORD_TYPE_UPDATED_INFO,       PTR_COUNT(__property_updated_info) },
+    {CALENDAR_VIEW_EVENT_CALENDAR,  CAL_RECORD_TYPE_SEARCH,             PTR_COUNT(__property_search_event_calendar) },
+    {CALENDAR_VIEW_TODO_CALENDAR,   CAL_RECORD_TYPE_SEARCH,             PTR_COUNT(__property_search_todo_calendar ) },
+    {CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE,  CAL_RECORD_TYPE_SEARCH,    PTR_COUNT(__property_search_event_calendar_attendee) },
+    {CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR, CAL_RECORD_TYPE_INSTANCE_NORMAL, PTR_COUNT(__property_search_instance_normal_calendar) },
+    {CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR, CAL_RECORD_TYPE_INSTANCE_ALLDAY, PTR_COUNT(__property_search_instance_allday_calendar) },
+    {CALENDAR_VIEW_EXTENDED, CAL_RECORD_TYPE_EXTENDED, PTR_COUNT(__property_extended) },
+};
+
+//////////////////////
+
+static bool cal_uri_property_flag = false;
+static GHashTable *cal_uri_property_hash = NULL;
+
+void _cal_view_initialize(void)
+{
+    bool bmutex = false;
+
+    if (cal_uri_property_flag == false)
+    {
+        _cal_mutex_lock(CAL_MUTEX_PROPERTY_HASH);
+        bmutex = true;
+    }
+
+    if ( cal_uri_property_hash == NULL)
+    {
+        cal_uri_property_hash = g_hash_table_new(g_str_hash, g_str_equal);
+        if (cal_uri_property_hash)
+        {
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_CALENDAR, GINT_TO_POINTER(&(__tables[0])) );
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_EVENT, GINT_TO_POINTER(&(__tables[1])) );
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_TODO, GINT_TO_POINTER(&(__tables[2])) );
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_TIMEZONE, GINT_TO_POINTER(&(__tables[3])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_ATTENDEE, GINT_TO_POINTER(&(__tables[4])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_ALARM, GINT_TO_POINTER(&(__tables[5])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_INSTANCE_NORMAL, GINT_TO_POINTER(&(__tables[6])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_INSTANCE_ALLDAY, GINT_TO_POINTER(&(__tables[7])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_UPDATED_INFO, GINT_TO_POINTER(&(__tables[8])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_EVENT_CALENDAR, GINT_TO_POINTER(&(__tables[9])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_TODO_CALENDAR, GINT_TO_POINTER(&(__tables[10])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE, GINT_TO_POINTER(&(__tables[11])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR, GINT_TO_POINTER(&(__tables[12])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR, GINT_TO_POINTER(&(__tables[13])));
+            g_hash_table_insert(cal_uri_property_hash, CALENDAR_VIEW_EXTENDED, GINT_TO_POINTER(&(__tables[14])));
+        }
+    }
+
+    if (bmutex == true)
+    {
+        cal_uri_property_flag = true;
+        _cal_mutex_unlock(CAL_MUTEX_PROPERTY_HASH);
+    }
+
+       return ;
+}
+
+cal_record_type_e _cal_view_get_type(const char *view_uri)
+{
+    cal_view_uri_info_s* view_uri_info = NULL;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    if(cal_uri_property_hash){
+        view_uri_info = g_hash_table_lookup(cal_uri_property_hash, view_uri);
+        if( view_uri_info ) {
+            type = view_uri_info->type;
+            //CAL_DBG("%s:%d",view_uri,type);
+        }
+               else
+               {
+                       ERR("g_hash_table_lookup() failed");
+               }
+    }
+       else
+       {
+               ERR("Unable to get cal_uri_property_hash");
+       }
+
+       return type;
+}
+
+void _cal_view_finalize(void)
+{
+#if 0
+    if( cal_uri_property_hash != NULL) {
+         g_hash_table_destroy(cal_uri_property_hash);
+         cal_uri_property_hash = NULL;
+    }
+#endif
+}
+
+const cal_property_info_s* _cal_view_get_property_info(const char *view_uri, int *count)
+{
+    cal_property_info_s* tmp = NULL;
+    cal_view_uri_info_s* view_uri_info = NULL;
+
+    if(cal_uri_property_hash){
+        view_uri_info = g_hash_table_lookup(cal_uri_property_hash, view_uri);
+        if( view_uri_info ) {
+            tmp = view_uri_info->properties;
+            *count = view_uri_info->property_count;
+        }
+    }
+
+    return tmp;
+}
+
+const char* _cal_view_get_uri(const char *view_uri)
+{
+    cal_view_uri_info_s* view_uri_info = NULL;
+
+    if(cal_uri_property_hash){
+        view_uri_info = g_hash_table_lookup(cal_uri_property_hash, view_uri);
+        if( view_uri_info ) {
+            return view_uri_info->view_uri;
+        }
+    }
+
+    return NULL;
+}
diff --git a/common/cal_view.h b/common/cal_view.h
new file mode 100644 (file)
index 0000000..0725bd2
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_VIEW_H__
+#define __CALENDAR_SVC_VIEW_H__
+
+#include "calendar_view.h"
+
+_CALENDAR_BEGIN_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+    _CALENDAR_PROPERTY_CALTIME( start_time )
+    _CALENDAR_PROPERTY_CALTIME( end_time )
+    _CALENDAR_PROPERTY_STR( summary )
+    _CALENDAR_PROPERTY_STR( location )
+    _CALENDAR_PROPERTY_INT( calendar_book_id )
+    _CALENDAR_PROPERTY_STR( description )
+    _CALENDAR_PROPERTY_INT( busy_status )
+    _CALENDAR_PROPERTY_INT( event_status )
+    _CALENDAR_PROPERTY_INT( priority )
+    _CALENDAR_PROPERTY_INT( sensitivity )
+    _CALENDAR_PROPERTY_INT( has_rrule )
+    _CALENDAR_PROPERTY_DOUBLE( latitude )
+    _CALENDAR_PROPERTY_DOUBLE( longitude )
+    _CALENDAR_PROPERTY_INT( has_alarm )
+    _CALENDAR_PROPERTY_INT( original_event_id )
+    _CALENDAR_PROPERTY_LLI( last_modified_time )
+_CALENDAR_END_VIEW( _calendar_instance_normal )    // read_only
+
+_CALENDAR_BEGIN_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+    _CALENDAR_PROPERTY_CALTIME( start_time )
+    _CALENDAR_PROPERTY_CALTIME( end_time )
+    _CALENDAR_PROPERTY_STR( summary )
+    _CALENDAR_PROPERTY_STR( location )
+    _CALENDAR_PROPERTY_INT( calendar_book_id )
+    _CALENDAR_PROPERTY_STR( description )
+    _CALENDAR_PROPERTY_INT( busy_status )
+    _CALENDAR_PROPERTY_INT( event_status )
+    _CALENDAR_PROPERTY_INT( priority )
+    _CALENDAR_PROPERTY_INT( sensitivity )
+    _CALENDAR_PROPERTY_INT( has_rrule )
+    _CALENDAR_PROPERTY_DOUBLE( latitude )
+    _CALENDAR_PROPERTY_DOUBLE( longitude )
+    _CALENDAR_PROPERTY_INT( has_alarm )
+    _CALENDAR_PROPERTY_INT( original_event_id )
+    _CALENDAR_PROPERTY_LLI( last_modified_time )
+_CALENDAR_END_VIEW( _calendar_instance_allday )    // read_only
+
+// db record view // get, get_list, insert, update, delete, filter
+#define CALENDAR_VIEW_CALENDAR              "tizen.calendar_view.calendar"
+#define CALENDAR_VIEW_EVENT                 "tizen.calendar_view.event"
+#define CALENDAR_VIEW_TODO                  "tizen.calendar_view.todo"
+#define CALENDAR_VIEW_TIMEZONE              "tizen.calendar_view.timezone"
+// child view
+#define CALENDAR_VIEW_ATTENDEE              "tizen.calendar_view.attendee"
+#define CALENDAR_VIEW_ALARM                 "tizen.calendar_view.alarm"
+
+// logical view  // get_list, filter
+#define CALENDAR_VIEW_INSTANCE_NORMAL       "tizen.calendar_view.instance_normal"
+#define CALENDAR_VIEW_INSTANCE_ALLDAY       "tizen.calendar_view.instance_allday"
+
+// updated info  // get_list
+#define CALENDAR_VIEW_UPDATED_INFO          "tizen.calendar_view.updated_info"
+
+// extended_table
+#define CALENDAR_VIEW_EXTENDED              "tizen,calendar_view.extended_property"
+
+// only for query (filter)
+#define CALENDAR_VIEW_EVENT_CALENDAR             "tizen.calendar_view.event/calendar"
+#define CALENDAR_VIEW_TODO_CALENDAR             "tizen.calendar_view.todo/calendar"
+#define CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE    "tizen.calendar_view.event/calendar/attendee"
+#define CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR   "tizen.calendar_view.instance_normal/calendar"
+#define CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR   "tizen.calendar_view.instance_allday/calendar"
+
+// for type check         // data_type mask 0x000FF000
+#define CAL_PROPERTY_DATA_TYPE_MASK             0x000FF000
+#define CAL_PROPERTY_DATA_TYPE_INT              0x00001000
+#define CAL_PROPERTY_DATA_TYPE_STR              0x00002000
+#define CAL_PROPERTY_DATA_TYPE_DOUBLE           0x00003000
+#define CAL_PROPERTY_DATA_TYPE_LLI              0x00004000
+#define CAL_PROPERTY_DATA_TYPE_CALTIME          0x00005000
+#define CAL_PROPERTY_DATA_TYPE_REC              0x00006000
+#define CAL_PROPERTY_CHECK_DATA_TYPE(property_id,data_type) \
+    ((property_id&CAL_PROPERTY_DATA_TYPE_MASK) == data_type ? true : false)
+// for property                             //  0xFF000000
+#define CAL_PROPERTY_MASK                       0xFF000000
+#define CAL_PROPERTY_CALENDAR                   0x01000000
+#define CAL_PROPERTY_EVENT                      0x02000000
+#define CAL_PROPERTY_TODO                       0x03000000
+#define CAL_PROPERTY_TIMEZONE                   0x04000000
+#define CAL_PROPERTY_ATTENDEE                   0x05000000
+#define CAL_PROPERTY_ALARM                      0x06000000
+#define CAL_PROPERTY_INSTANCE_NORMAL            0x07000000
+#define CAL_PROPERTY_INSTANCE_ALLDAY            0x08000000
+#define CAL_PROPERTY_UPDATED_INFO               0x09000000
+#define CAL_PROPERTY_EXTENDED                   0x0A000000
+#define CAL_PROPERTY_CHECK(property_id,data_type) \
+    ((property_id&CAL_PROPERTY_MASK) == data_type ? true : false)
+
+#define CAL_PROPERTY_FLAGS_MASK                 0x00F00000
+#define CAL_PROPERTY_FLAGS_FILTER               0x00100000
+#define CAL_PROPERTY_FLAGS_PROJECTION           0x00200000
+#define CAL_PROPERTY_FLAGS_READ_ONLY            0x00300000
+#define CAL_PROPERTY_CHECK_FLAGS(property_id,data_type) \
+    ((property_id&CAL_PROPERTY_FLAGS_MASK) == data_type ? true : false)
+
+typedef enum {
+       CAL_PROPERTY_CALENDAR_ID                = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY),
+       CAL_PROPERTY_CALENDAR_UID               = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +1,
+       CAL_PROPERTY_CALENDAR_NAME              = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +2,
+       CAL_PROPERTY_CALENDAR_DESCRIPTION       = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +3,
+       CAL_PROPERTY_CALENDAR_COLOR             = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +4,
+       CAL_PROPERTY_CALENDAR_LOCATION          = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +5,
+       CAL_PROPERTY_CALENDAR_VISIBILITY        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_INT) +6,
+       CAL_PROPERTY_CALENDAR_SYNC_EVENT        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_INT) +7,
+       CAL_PROPERTY_CALENDAR_IS_DELETED        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_INT) +8,
+       CAL_PROPERTY_CALENDAR_ACCOUNT_ID        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_INT) +9,
+       CAL_PROPERTY_CALENDAR_STORE_TYPE        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_INT) +10,
+       CAL_PROPERTY_CALENDAR_SYNC_DATA1        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +11,
+       CAL_PROPERTY_CALENDAR_SYNC_DATA2        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +12,
+       CAL_PROPERTY_CALENDAR_SYNC_DATA3        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +13,
+       CAL_PROPERTY_CALENDAR_SYNC_DATA4        = (CAL_PROPERTY_CALENDAR|CAL_PROPERTY_DATA_TYPE_STR) +14,
+
+       CAL_PROPERTY_EVENT_ID                   = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY),
+       CAL_PROPERTY_EVENT_CALENDAR_ID          = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +1,
+       CAL_PROPERTY_EVENT_SUMMARY              = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +2,
+       CAL_PROPERTY_EVENT_DESCRIPTION          = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +3,
+       CAL_PROPERTY_EVENT_LOCATION             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +4,
+       CAL_PROPERTY_EVENT_CATEGORIES           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +5,
+       CAL_PROPERTY_EVENT_EXDATE               = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +6,
+       CAL_PROPERTY_EVENT_EVENT_STATUS         = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +7,
+       CAL_PROPERTY_EVENT_PRIORITY             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +8,
+       CAL_PROPERTY_EVENT_TIMEZONE             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +9,
+       CAL_PROPERTY_EVENT_CONTACT_ID           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +10,
+       CAL_PROPERTY_EVENT_BUSY_STATUS          = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +11,
+       CAL_PROPERTY_EVENT_SENSITIVITY          = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +12,
+       CAL_PROPERTY_EVENT_UID                  = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +13,
+       CAL_PROPERTY_EVENT_ORGANIZER_NAME       = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +14,
+       CAL_PROPERTY_EVENT_ORGANIZER_EMAIL      = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +15,
+       CAL_PROPERTY_EVENT_MEETING_STATUS       = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +16,
+       CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID    = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +17,
+       CAL_PROPERTY_EVENT_LATITUDE             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_DOUBLE) +18,
+       CAL_PROPERTY_EVENT_LONGITUDE            = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_DOUBLE) +19,
+       CAL_PROPERTY_EVENT_EMAIL_ID             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +20,
+       CAL_PROPERTY_EVENT_CREATED_TIME         = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_LLI) +21,
+       CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME   = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_LLI) +22,
+       CAL_PROPERTY_EVENT_IS_DELETED           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +23,
+       CAL_PROPERTY_EVENT_FREQ                 = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +24,
+       CAL_PROPERTY_EVENT_RANGE_TYPE           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +25,
+       CAL_PROPERTY_EVENT_UNTIL                = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_CALTIME) +26,
+       CAL_PROPERTY_EVENT_COUNT                = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +27,
+       CAL_PROPERTY_EVENT_INTERVAL             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +28,
+       CAL_PROPERTY_EVENT_BYSECOND             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +29,
+       CAL_PROPERTY_EVENT_BYMINUTE             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +30,
+       CAL_PROPERTY_EVENT_BYHOUR               = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +31,
+       CAL_PROPERTY_EVENT_BYDAY                = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +32,
+       CAL_PROPERTY_EVENT_BYMONTHDAY           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +33,
+       CAL_PROPERTY_EVENT_BYYEARDAY            = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +34,
+       CAL_PROPERTY_EVENT_BYWEEKNO             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +35,
+       CAL_PROPERTY_EVENT_BYMONTH              = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +36,
+       CAL_PROPERTY_EVENT_BYSETPOS             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +37,
+       CAL_PROPERTY_EVENT_WKST                 = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +38,
+       CAL_PROPERTY_EVENT_RECURRENCE_ID        = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +39,
+       CAL_PROPERTY_EVENT_RDATE                = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +40,
+       CAL_PROPERTY_EVENT_HAS_ATTENDEE         = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +41,
+       CAL_PROPERTY_EVENT_HAS_ALARM            = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +42,
+       CAL_PROPERTY_EVENT_SYNC_DATA1           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +43,
+       CAL_PROPERTY_EVENT_SYNC_DATA2           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +44,
+       CAL_PROPERTY_EVENT_SYNC_DATA3           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +45,
+       CAL_PROPERTY_EVENT_SYNC_DATA4           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +46,
+       CAL_PROPERTY_EVENT_START                = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_CALTIME) +47,
+       CAL_PROPERTY_EVENT_END                  = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_CALTIME) +48,
+       CAL_PROPERTY_EVENT_CALENDAR_ALARM       = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_REC) +49,
+       CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE    = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_REC) +50,
+    CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT) +51,
+    CAL_PROPERTY_EVENT_START_TZID           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +52,
+    CAL_PROPERTY_EVENT_END_TZID             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_STR) +53,
+    CAL_PROPERTY_EVENT_EXCEPTION            = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_REC) +54,
+    CAL_PROPERTY_EVENT_EXTENDED             = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_REC) +55,
+    CAL_PROPERTY_EVENT_IS_ALLDAY            = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +56,
+
+       CAL_PROPERTY_TODO_ID                    =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY),
+       CAL_PROPERTY_TODO_CALENDAR_ID           =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +1,
+       CAL_PROPERTY_TODO_SUMMARY               =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +2,
+       CAL_PROPERTY_TODO_DESCRIPTION           =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +3,
+       CAL_PROPERTY_TODO_LOCATION              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +4,
+       CAL_PROPERTY_TODO_CATEGORIES            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +5,
+       CAL_PROPERTY_TODO_TODO_STATUS           =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +6,
+       CAL_PROPERTY_TODO_PRIORITY              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +7,
+       CAL_PROPERTY_TODO_SENSITIVITY           =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +8,
+       CAL_PROPERTY_TODO_UID                   =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +9,
+       CAL_PROPERTY_TODO_LATITUDE              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_DOUBLE) +10,
+       CAL_PROPERTY_TODO_LONGITUDE             =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_DOUBLE) +11,
+       CAL_PROPERTY_TODO_PROGRESS              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +12,
+       CAL_PROPERTY_TODO_CREATED_TIME          =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_LLI) +13,
+       CAL_PROPERTY_TODO_LAST_MODIFIED_TIME    =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_LLI) +14,
+       CAL_PROPERTY_TODO_COMPLETED_TIME        =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_LLI) +15,
+       CAL_PROPERTY_TODO_IS_DELETED            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +16,
+       CAL_PROPERTY_TODO_FREQ                  =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +17,
+       CAL_PROPERTY_TODO_RANGE_TYPE            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +18,
+       CAL_PROPERTY_TODO_UNTIL                 =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_CALTIME) +19,
+       CAL_PROPERTY_TODO_COUNT                 =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +20,
+       CAL_PROPERTY_TODO_INTERVAL              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +21,
+       CAL_PROPERTY_TODO_BYSECOND              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +22,
+       CAL_PROPERTY_TODO_BYMINUTE              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +23,
+       CAL_PROPERTY_TODO_BYHOUR                =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +24,
+       CAL_PROPERTY_TODO_BYDAY                 =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +25,
+       CAL_PROPERTY_TODO_BYMONTHDAY            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +26,
+       CAL_PROPERTY_TODO_BYYEARDAY             =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +27,
+       CAL_PROPERTY_TODO_BYWEEKNO              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +28,
+       CAL_PROPERTY_TODO_BYMONTH               =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +29,
+       CAL_PROPERTY_TODO_BYSETPOS              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +30,
+       CAL_PROPERTY_TODO_WKST                  =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) +31,
+       CAL_PROPERTY_TODO_HAS_ALARM             =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +32,
+       CAL_PROPERTY_TODO_SYNC_DATA1            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +33,
+       CAL_PROPERTY_TODO_SYNC_DATA2            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +34,
+       CAL_PROPERTY_TODO_SYNC_DATA3            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +35,
+       CAL_PROPERTY_TODO_SYNC_DATA4            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +36,
+       CAL_PROPERTY_TODO_START                 =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_CALTIME) +37,
+       CAL_PROPERTY_TODO_DUE                   =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_CALTIME) +38,
+       CAL_PROPERTY_TODO_CALENDAR_ALARM        =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_REC) +39,
+    CAL_PROPERTY_TODO_START_TZID            =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +40,
+    CAL_PROPERTY_TODO_DUE_TZID              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +41,
+    CAL_PROPERTY_TODO_ORGANIZER_NAME        =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +42,
+    CAL_PROPERTY_TODO_ORGANIZER_EMAIL       =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_STR) +43,
+    CAL_PROPERTY_TODO_HAS_ATTENDEE          =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +44,
+    CAL_PROPERTY_TODO_CALENDAR_ATTENDEE     =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_REC) +45,
+    CAL_PROPERTY_TODO_EXTENDED              =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_REC) +46,
+    CAL_PROPERTY_TODO_IS_ALLDAY             =(CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) +47,
+
+       CAL_PROPERTY_TIMEZONE_ID                                                                =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY),
+       CAL_PROPERTY_TIMEZONE_TZ_OFFSET_FROM_GMT                =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+1,
+       CAL_PROPERTY_TIMEZONE_STANDARD_NAME                     =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_STR)+2,
+       CAL_PROPERTY_TIMEZONE_STD_START_MONTH                   =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+3,
+       CAL_PROPERTY_TIMEZONE_STD_START_POSITION_OF_WEEK        =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+4,
+       CAL_PROPERTY_TIMEZONE_STD_START_DAY                     =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+5,
+       CAL_PROPERTY_TIMEZONE_STD_START_HOUR                    =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+6,
+       CAL_PROPERTY_TIMEZONE_STANDARD_BIAS                     =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+7,
+       CAL_PROPERTY_TIMEZONE_DAY_LIGHT_NAME                    =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_STR)+8,
+       CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_MONTH             =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+9,
+       CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_POSITION_OF_WEEK  =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+10,
+       CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_DAY               =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+11,
+       CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_HOUR              =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+12,
+       CAL_PROPERTY_TIMEZONE_DAY_LIGHT_BIAS                    =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+13,
+       CAL_PROPERTY_TIMEZONE_CALENDAR_ID                       =(CAL_PROPERTY_TIMEZONE|CAL_PROPERTY_DATA_TYPE_INT)+14,
+
+
+       CAL_PROPERTY_ATTENDEE_NUMBER            =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_STR),
+       CAL_PROPERTY_ATTENDEE_TYPE              =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_INT)+1,
+       CAL_PROPERTY_ATTENDEE_CT_INDEX          =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_INT)+2,
+       CAL_PROPERTY_ATTENDEE_UID               =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_STR)+3,
+       CAL_PROPERTY_ATTENDEE_GROUP             =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_STR)+4,
+       CAL_PROPERTY_ATTENDEE_EMAIL             =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_STR)+5,
+       CAL_PROPERTY_ATTENDEE_ROLE              =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_INT)+6,
+       CAL_PROPERTY_ATTENDEE_STATUS            =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_INT)+7,
+       CAL_PROPERTY_ATTENDEE_RSVP              =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_INT)+8,
+       CAL_PROPERTY_ATTENDEE_DELEGATE_URI      =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_STR)+9,
+       CAL_PROPERTY_ATTENDEE_DELEGATOR_URI     =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_STR)+10,
+       CAL_PROPERTY_ATTENDEE_NAME              =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_STR)+11,
+       CAL_PROPERTY_ATTENDEE_EVENT_ID          =(CAL_PROPERTY_ATTENDEE|CAL_PROPERTY_DATA_TYPE_INT)+12,
+
+       CAL_PROPERTY_ALARM_TYPE                 =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_INT),
+       CAL_PROPERTY_ALARM_TIME                 =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_LLI)+1,
+       CAL_PROPERTY_ALARM_TICK                 =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_INT)+2,
+       CAL_PROPERTY_ALARM_TICK_UNIT            =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_INT)+3,
+       CAL_PROPERTY_ALARM_TONE                 =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_STR)+4,
+       CAL_PROPERTY_ALARM_DESCRIPTION          =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_STR)+5,
+       CAL_PROPERTY_ALARM_ID                   =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_INT)+6,
+       CAL_PROPERTY_ALARM_EVENT_TODO_ID        =(CAL_PROPERTY_ALARM|CAL_PROPERTY_DATA_TYPE_INT)+7,
+
+    CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID       =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT),
+       CAL_PROPERTY_INSTANCE_NORMAL_START          =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_CALTIME) +1,
+       CAL_PROPERTY_INSTANCE_NORMAL_END            =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_CALTIME) +2,
+       CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY        =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_STR)+3,
+       CAL_PROPERTY_INSTANCE_NORMAL_LOCATION       =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_STR)+4,
+       CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID    =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+5,
+       CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION    =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_STR)+6,
+       CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS    =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+7,
+       CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS   =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+8,
+       CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY       =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+9,
+       CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY    =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+10,
+       CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE      =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+11,
+       CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE       =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_DOUBLE)+12,
+       CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE      =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_DOUBLE)+13,
+       CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM      =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+14,
+       CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID  =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT)+15,
+       CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_LLI)+16,
+
+    CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID       =(CAL_PROPERTY_INSTANCE_NORMAL|CAL_PROPERTY_DATA_TYPE_INT),
+       CAL_PROPERTY_INSTANCE_ALLDAY_START          =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_CALTIME) +1,
+    CAL_PROPERTY_INSTANCE_ALLDAY_END            =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_CALTIME) +2,
+       CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY        =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_STR)+3,
+       CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION       =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_STR)+4,
+       CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID    =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+5,
+       CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION    =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_STR)+6,
+       CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS    =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+7,
+       CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS   =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+8,
+       CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY       =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+9,
+       CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY    =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+10,
+       CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE      =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+11,
+       CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE       =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_DOUBLE)+12,
+       CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE      =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_DOUBLE)+13,
+       CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM      =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+14,
+       CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID  =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_INT)+15,
+       CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME =(CAL_PROPERTY_INSTANCE_ALLDAY|CAL_PROPERTY_DATA_TYPE_LLI)+16,
+
+       CAL_PROPERTY_UPDATED_INFO_ID                =(CAL_PROPERTY_UPDATED_INFO|CAL_PROPERTY_DATA_TYPE_INT),
+       CAL_PROPERTY_UPDATED_INFO_CALENDAR_ID       =(CAL_PROPERTY_UPDATED_INFO|CAL_PROPERTY_DATA_TYPE_INT)+1,
+       CAL_PROPERTY_UPDATED_INFO_TYPE              =(CAL_PROPERTY_UPDATED_INFO|CAL_PROPERTY_DATA_TYPE_INT)+2,
+       CAL_PROPERTY_UPDATED_INFO_VERSION           =(CAL_PROPERTY_UPDATED_INFO|CAL_PROPERTY_DATA_TYPE_INT)+3,
+
+       CAL_PROPERTY_EXTENDED_ID                    =(CAL_PROPERTY_EXTENDED|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY),
+       CAL_PROPERTY_EXTENDED_RECORD_ID             =(CAL_PROPERTY_EXTENDED|CAL_PROPERTY_DATA_TYPE_INT)+1,
+       CAL_PROPERTY_EXTENDED_RECORD_TYPE           =(CAL_PROPERTY_EXTENDED|CAL_PROPERTY_DATA_TYPE_INT)+2,
+       CAL_PROPERTY_EXTENDED_KEY                   =(CAL_PROPERTY_EXTENDED|CAL_PROPERTY_DATA_TYPE_STR)+3,
+       CAL_PROPERTY_EXTENDED_VALUE                 =(CAL_PROPERTY_EXTENDED|CAL_PROPERTY_DATA_TYPE_STR)+4,
+
+} cal_property_ids_e;
+
+void _cal_view_initialize(void);
+cal_record_type_e _cal_view_get_type(const char *view_uri);
+void _cal_view_finalize(void);
+
+const cal_property_info_s* _cal_view_get_property_info(const char *view_uri, int *count);
+
+const char* _cal_view_get_uri(const char *view_uri);
+
+#endif /* __CALENDAR_SVC_VIEW_H__ */
diff --git a/common/ipc/cal_ipc.h b/common/ipc/cal_ipc.h
new file mode 100644 (file)
index 0000000..c67f2b5
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CAL_IPC_H__
+#define __CAL_IPC_H__
+
+#define CAL_IPC_SERVICE              "cal_svc_ipc"
+#define CAL_IPC_SOCKET_PATH          "/opt/usr/data/calendar-svc/."CAL_IPC_SERVICE
+#define CAL_IPC_MODULE               "cal_ipc_module"
+
+#define CAL_IPC_SERVER_CONNECT                      "connect"
+#define CAL_IPC_SERVER_DISCONNECT                   "disconnect"
+#define CAL_IPC_SERVER_DB_INSERT_RECORD             "insert_record"
+#define CAL_IPC_SERVER_DB_GET_RECORD                "get_record"
+#define CAL_IPC_SERVER_DB_UPDATE_RECORD             "update_record"
+#define CAL_IPC_SERVER_DB_DELETE_RECORD             "delete_record"
+#define CAL_IPC_SERVER_DB_GET_ALL_RECORDS           "get_all_records"
+#define CAL_IPC_SERVER_DB_GET_RECORDS_WITH_QUERY    "get_records_with_query"
+#define CAL_IPC_SERVER_DB_CLEAN_AFTER_SYNC          "clean_after_sync"
+#define CAL_IPC_SERVER_DB_GET_COUNT                 "get_count"
+#define CAL_IPC_SERVER_DB_GET_COUNT_WITH_QUERY      "get_count_with_query"
+#define CAL_IPC_SERVER_DB_INSERT_RECORDS            "insert_records"
+#define CAL_IPC_SERVER_DB_UPDATE_RECORDS            "update_records"
+#define CAL_IPC_SERVER_DB_DELETE_RECORDS            "delete_records"
+#define CAL_IPC_SERVER_DB_CHANGES_BY_VERSION        "changes_by_version"
+#define CAL_IPC_SERVER_DB_GET_CURRENT_VERSION       "get_current_version"
+#define CAL_IPC_SERVER_DB_INSERT_VCALENDARS         "insert_vcalendars"
+#define CAL_IPC_SERVER_DB_REPLACE_VCALENDARS        "replace_vcalendars"
+#define CAL_IPC_SERVER_DB_REPLACE_RECORD            "replace_record"
+#define CAL_IPC_SERVER_DB_REPLACE_RECORDS           "replace_records"
+
+#define CAL_IPC_SERVER_DB_REGISTER_REMINDER         "register_reminder"
+#define CAL_IPC_SERVER_DB_UNREGISTER_REMINDER       "unregister_reminder"
+#define CAL_IPC_SERVER_DB_ACTIVATE_REMINDER         "activate_reminder"
+#define CAL_IPC_SERVER_DB_DEACTIVATE_REMINDER       "deactivate_reminder"
+#define CAL_IPC_SERVER_DB_HAS_REMINDER              "has_reminder"
+
+#endif /*__CAL_IPC_H__*/
diff --git a/common/ipc/cal_ipc_marshal.c b/common/ipc/cal_ipc_marshal.c
new file mode 100644 (file)
index 0000000..7ac5984
--- /dev/null
@@ -0,0 +1,1180 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "calendar_query.h"
+#include "calendar_filter.h"
+#include "calendar_list.h"
+
+#include "cal_ipc_marshal.h"
+#include "cal_record.h"
+#include "cal_internal.h"
+#include "cal_view.h"
+
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_calendar_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_event_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_todo_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_alarm_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_attendee_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_timezone_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_updated_info_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_instance_normal_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_instance_allday_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_search_plugin_cb;
+extern cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_extended_plugin_cb;
+
+static cal_ipc_marshal_record_plugin_cb_s* __cal_ipc_marshal_get_plugin_cb(cal_record_type_e type);
+
+static int __cal_ipc_unmarshal_composite_filter(const pims_ipc_data_h ipc_data, cal_composite_filter_s* filter);
+static int __cal_ipc_marshal_composite_filter(const cal_composite_filter_s* filter, pims_ipc_data_h ipc_data);
+static int __cal_ipc_unmarshal_attribute_filter(const pims_ipc_data_h ipc_data, const cal_filter_type_e filter_type, cal_attribute_filter_s* filter);
+static int __cal_ipc_marshal_attribute_filter(const cal_attribute_filter_s* filter, pims_ipc_data_h ipc_data);
+
+static cal_ipc_marshal_record_plugin_cb_s* __cal_ipc_marshal_get_plugin_cb(cal_record_type_e type)
+{
+    switch (type)
+    {
+    case CAL_RECORD_TYPE_CALENDAR:
+        return (&_cal_ipc_record_calendar_plugin_cb);
+    case CAL_RECORD_TYPE_EVENT:
+        return (&_cal_ipc_record_event_plugin_cb);
+    case CAL_RECORD_TYPE_TODO:
+        return (&_cal_ipc_record_todo_plugin_cb);
+    case CAL_RECORD_TYPE_ALARM:
+        return (&_cal_ipc_record_alarm_plugin_cb);
+    case CAL_RECORD_TYPE_ATTENDEE:
+        return (&_cal_ipc_record_attendee_plugin_cb);
+    case CAL_RECORD_TYPE_TIMEZONE:
+        return (&_cal_ipc_record_timezone_plugin_cb);
+    case CAL_RECORD_TYPE_INSTANCE_NORMAL:
+        return (&_cal_ipc_record_instance_normal_plugin_cb);
+    case CAL_RECORD_TYPE_INSTANCE_ALLDAY:
+        return (&_cal_ipc_record_instance_allday_plugin_cb);
+    case CAL_RECORD_TYPE_UPDATED_INFO:
+        return (&_cal_ipc_record_updated_info_plugin_cb);
+    case CAL_RECORD_TYPE_SEARCH:
+        return (&_cal_ipc_record_search_plugin_cb);
+    case CAL_RECORD_TYPE_EXTENDED:
+        return (&_cal_ipc_record_extended_plugin_cb);
+    default:
+        return NULL;
+    }
+}
+
+static int __cal_ipc_unmarshal_composite_filter(const pims_ipc_data_h ipc_data, cal_composite_filter_s* filter)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    unsigned int size = 0;
+    char* str = NULL;
+    int count =0, i=0;
+    cal_filter_type_e filter_type = CAL_FILTER_COMPOSITE;
+    calendar_filter_operator_e op = CALENDAR_FILTER_OPERATOR_AND;
+
+/*
+    if (_cal_ipc_unmarshal_int(ipc_data,&(filter->filter_type)) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+*/
+    filter->filter_type = CAL_FILTER_COMPOSITE;
+
+    // view_uri
+    str = (char*)pims_ipc_data_get(ipc_data,&size);
+    filter->view_uri = strdup(str);
+
+    // filters
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&filter_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            ret = CALENDAR_ERROR_INVALID_PARAMETER;
+            goto ERROR_RETURN;
+        }
+        if (filter_type == CAL_FILTER_COMPOSITE)
+        {
+            cal_composite_filter_s* com_filter = NULL;
+            com_filter = (cal_composite_filter_s*)calloc(1,sizeof(cal_composite_filter_s));
+            if (com_filter == NULL)
+            {
+                ERR("malloc fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto ERROR_RETURN;
+            }
+            if (__cal_ipc_unmarshal_composite_filter(ipc_data, com_filter) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_unmarshal fail");
+                ret = CALENDAR_ERROR_INVALID_PARAMETER;
+                CAL_FREE(com_filter);
+                goto ERROR_RETURN;
+            }
+            filter->filters = g_slist_append(filter->filters,com_filter);
+        }
+        else
+        {
+            cal_attribute_filter_s* attr_filter = NULL;
+            attr_filter = (cal_attribute_filter_s*)calloc(1,sizeof(cal_attribute_filter_s));
+            if (attr_filter == NULL)
+            {
+                ERR("malloc fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto ERROR_RETURN;
+            }
+            if (__cal_ipc_unmarshal_attribute_filter(ipc_data, filter_type, attr_filter) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_unmarshal fail");
+                ret =  CALENDAR_ERROR_INVALID_PARAMETER;
+                CAL_FREE(attr_filter);
+                goto ERROR_RETURN;
+            }
+            filter->filters = g_slist_append(filter->filters,attr_filter);
+        }
+    }
+
+    // filters
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        ret =  CALENDAR_ERROR_INVALID_PARAMETER;
+        goto ERROR_RETURN;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&op) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            ret =  CALENDAR_ERROR_INVALID_PARAMETER;
+            goto ERROR_RETURN;
+        }
+        filter->filter_ops = g_slist_append(filter->filter_ops, (void*)op);
+    }
+
+    // properties //property_count
+    filter->properties = (cal_property_info_s *)_cal_view_get_property_info(filter->view_uri, &filter->property_count);
+
+    return CALENDAR_ERROR_NONE;
+
+ERROR_RETURN:
+
+    if (filter->filters)
+    {
+        GSList *cursor = NULL;
+        for(cursor=filter->filters;cursor;cursor=cursor->next)
+        {
+            cal_filter_s *src = (cal_filter_s*)cursor->data;
+            CAL_FREE(src);
+        }
+        g_slist_free(filter->filters);
+    }
+
+    if (filter->filter_ops)
+    {
+        g_slist_free(filter->filter_ops);
+    }
+
+    return ret;
+}
+
+static int __cal_ipc_marshal_composite_filter(const cal_composite_filter_s* filter, pims_ipc_data_h ipc_data)
+{
+    if (_cal_ipc_marshal_int((filter->filter_type),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_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)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    // filter->filters
+    if (filter->filters)
+    {
+        int count = g_slist_length(filter->filters);
+        GSList *cursor = filter->filters;
+        cal_filter_s* child_filter;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            child_filter = (cal_filter_s*)cursor->data;
+
+            if (child_filter->filter_type == CAL_FILTER_COMPOSITE)
+            {
+                if (__cal_ipc_marshal_composite_filter((cal_composite_filter_s*)child_filter, ipc_data) != CALENDAR_ERROR_NONE)
+                {
+                    ERR("__cal_ipc_marshal_composite_filter fail");
+                    return CALENDAR_ERROR_INVALID_PARAMETER;
+                }
+            }
+            else
+            {
+                if (__cal_ipc_marshal_attribute_filter((cal_attribute_filter_s*)child_filter, ipc_data) != CALENDAR_ERROR_NONE)
+                {
+                    ERR("__cal_ipc_marshal_attribute_filter fail");
+                    return CALENDAR_ERROR_INVALID_PARAMETER;
+                }
+            }
+            cursor = g_slist_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (filter->filter_ops)
+    {
+        int count = g_slist_length(filter->filter_ops);
+        GSList *cursor = filter->filter_ops;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            calendar_filter_operator_e op = (calendar_filter_operator_e)cursor->data;
+
+            if (_cal_ipc_marshal_int(op,ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+
+            cursor = g_slist_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    // properties //property_count
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_unmarshal_attribute_filter(const pims_ipc_data_h ipc_data, const cal_filter_type_e filter_type, cal_attribute_filter_s* filter)
+{
+    filter->filter_type = filter_type;
+    if (_cal_ipc_unmarshal_int(ipc_data,&filter->property_id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_unmarshal_int(ipc_data,&filter->match) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    switch(filter->filter_type)
+    {
+    case CAL_FILTER_STR:
+        if (_cal_ipc_unmarshal_char(ipc_data,&filter->value.s) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_INT:
+        if (_cal_ipc_unmarshal_int(ipc_data,&filter->value.i) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_DOUBLE:
+        if (_cal_ipc_unmarshal_double(ipc_data,&filter->value.d) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_LLI:
+        if (_cal_ipc_unmarshal_lli(ipc_data,&filter->value.lli) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_CALTIME:
+        if (_cal_ipc_unmarshal_caltime(ipc_data,&filter->value.caltime) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    default:
+        break;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_attribute_filter(const cal_attribute_filter_s* filter, pims_ipc_data_h ipc_data)
+{
+    if (_cal_ipc_marshal_int((filter->filter_type),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int((filter->property_id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int((filter->match),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    switch(filter->filter_type)
+    {
+    case CAL_FILTER_STR:
+        if (_cal_ipc_marshal_char((filter->value.s),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_INT:
+        if (_cal_ipc_marshal_int((filter->value.i),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_DOUBLE:
+        if (_cal_ipc_marshal_double((filter->value.d),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_LLI:
+        if (_cal_ipc_marshal_lli((filter->value.lli),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    case CAL_FILTER_CALTIME:
+        if (_cal_ipc_marshal_caltime((filter->value.caltime),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        break;
+    default:
+        break;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_record(const pims_ipc_data_h ipc_data, calendar_record_h* precord)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    cal_record_s common = {0,};
+    cal_record_s *pcommon = NULL;
+
+    if (_cal_ipc_unmarshal_record_common(ipc_data,&common) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    retvm_if(NULL == precord || NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    cal_ipc_marshal_record_plugin_cb_s *plugin_cb = __cal_ipc_marshal_get_plugin_cb(common.type);
+
+    retvm_if(NULL == plugin_cb || NULL == plugin_cb->unmarshal_record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_record_create(common.view_uri, precord);
+    retvm_if(ret != CALENDAR_ERROR_NONE, ret, "record create fail");
+
+    pcommon = (cal_record_s*)(*precord);
+    pcommon->properties_max_count = common.properties_max_count;
+    pcommon->properties_flags = common.properties_flags;
+
+    ret = plugin_cb->unmarshal_record(ipc_data, *precord);
+
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        calendar_record_destroy(*precord,true);
+        *precord = NULL;
+        ERR("_cal_ipc_unmarshal fail");
+    }
+
+    return ret;
+}
+
+int _cal_ipc_marshal_record(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    cal_ipc_marshal_record_plugin_cb_s *plugin_cb = __cal_ipc_marshal_get_plugin_cb(temp->type);
+
+    retvm_if(NULL == plugin_cb || NULL == plugin_cb->marshal_record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = plugin_cb->marshal_record(record, ipc_data);
+
+    return ret;
+}
+
+int _cal_ipc_marshal_record_get_primary_id(const calendar_record_h record,
+        unsigned int *property_id, int *id)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    cal_record_s *temp = (cal_record_s*)(record);
+
+    retvm_if(NULL == record || NULL == property_id ||
+            NULL == id, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    cal_ipc_marshal_record_plugin_cb_s *plugin_cb = __cal_ipc_marshal_get_plugin_cb(temp->type);
+
+    retvm_if(NULL == plugin_cb || NULL == plugin_cb->get_primary_id, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = plugin_cb->get_primary_id(record, property_id,id);
+
+    return ret;
+}
+
+int _cal_ipc_unmarshal_char(const pims_ipc_data_h ipc_data, char** ppbufchar)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    void *tmp = NULL;
+    unsigned int size = 0;
+    char *str = NULL;
+
+    int length = 0;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(ppbufchar==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    tmp = pims_ipc_data_get(ipc_data,&size);
+    if ( tmp == NULL){
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    length = *(int*)tmp;
+
+    if(length == -1)
+    {
+        ret = CALENDAR_ERROR_NONE;
+        //CAL_DBG("string is null");
+        *ppbufchar = NULL;
+        return ret;
+    }
+
+    str = (char*)pims_ipc_data_get(ipc_data,&size);
+    if (str)
+    {
+        *ppbufchar = SAFE_STRDUP(str);
+    }
+    //CAL_DBG("string set %s",*ppbufchar);
+
+    return ret;
+}
+
+int _cal_ipc_unmarshal_int(const pims_ipc_data_h data, int *pout)
+{
+    void *tmp = NULL;
+    unsigned int size = 0;
+
+    retv_if(data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(pout==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    tmp = pims_ipc_data_get(data,&size);
+    if ( tmp == NULL)
+    {
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    else
+    {
+        *pout = *(int*)tmp;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_uint(const pims_ipc_data_h data, unsigned int *pout)
+{
+    void *tmp = NULL;
+    unsigned int size = 0;
+
+    retv_if(data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(pout==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    tmp = pims_ipc_data_get(data,&size);
+    if ( tmp == NULL)
+    {
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    else
+    {
+        *pout = *(unsigned int*)tmp;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_lli(const pims_ipc_data_h data, long long int *pout)
+{
+    void *tmp = NULL;
+    unsigned int size = 0;
+
+    retv_if(data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(pout==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    tmp = pims_ipc_data_get(data,&size);
+    if ( tmp == NULL)
+    {
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    else
+    {
+        *pout = *(long long int*)tmp;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_long(const pims_ipc_data_h data, long *pout)
+{
+    void *tmp = NULL;
+    unsigned int size = 0;
+
+    retv_if(data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(pout==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    tmp = pims_ipc_data_get(data,&size);
+    if ( tmp == NULL)
+    {
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    else
+    {
+        *pout = *(long*)tmp;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_double(const pims_ipc_data_h data, double *pout)
+{
+    void *tmp = NULL;
+    unsigned int size = 0;
+
+    retv_if(data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(pout==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    tmp = pims_ipc_data_get(data,&size);
+    if ( tmp == NULL)
+    {
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    else
+    {
+        *pout = *(double*)tmp;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_caltime(const pims_ipc_data_h data, calendar_time_s *pout)
+{
+    void *tmp = NULL;
+    unsigned int size = 0;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(pout==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    tmp = pims_ipc_data_get(data,&size);
+    if ( tmp == NULL)
+    {
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    else
+    {
+        pout->type = *(int*)tmp;
+    }
+
+    if (pout->type == CALENDAR_TIME_UTIME)
+    {
+        return _cal_ipc_unmarshal_lli(data, &(pout->time.utime));
+    }
+    else
+    {
+        ret = _cal_ipc_unmarshal_int(data, &(pout->time.date.year));
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+        ret = _cal_ipc_unmarshal_int(data, &(pout->time.date.month));
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+        ret = _cal_ipc_unmarshal_int(data, &(pout->time.date.mday));
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_record_common(const pims_ipc_data_h ipc_data, cal_record_s* common)
+{
+    void *tmp = NULL;
+    unsigned int size = 0;
+    const char* str = NULL;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    tmp = pims_ipc_data_get(ipc_data,&size);
+    if ( tmp == NULL)
+    {
+        ERR("pims_ipc_data_get fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    else
+    {
+        common->type = *(cal_record_type_e*)tmp;
+    }
+
+    common->plugin_cb = _cal_record_get_plugin_cb(common->type);
+
+    str = (char*)pims_ipc_data_get(ipc_data,&size);
+    common->view_uri = _cal_view_get_uri(str);
+
+    tmp = pims_ipc_data_get(ipc_data,&size);
+
+    common->properties_max_count = *(unsigned int*)tmp;
+    if (common->properties_max_count > 0)
+    {
+        unsigned char *tmp_properties_flags;
+        tmp_properties_flags = (unsigned char*)pims_ipc_data_get(ipc_data,&size);
+        common->properties_flags  = calloc(common->properties_max_count, sizeof(char));
+        if (common->properties_flags == NULL)
+        {
+            ERR("calloc fail");
+            return CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+        memcpy(common->properties_flags,tmp_properties_flags,sizeof(char)*common->properties_max_count);
+    }
+
+    tmp = pims_ipc_data_get(ipc_data,&size);
+    common->property_flag = *(unsigned char*)tmp;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_marshal_char(const char* bufchar, pims_ipc_data_h ipc_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if( bufchar != NULL)
+    {
+        int length = strlen(bufchar);
+        if (pims_ipc_data_put(ipc_data,(void*)&length,sizeof(int)) != 0)
+        {
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+
+        if ( pims_ipc_data_put(ipc_data,(void*)bufchar,length+1) != 0)
+        {
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+            return ret;
+        }
+    }
+    else
+    {
+        int length = -1;
+
+        if (pims_ipc_data_put(ipc_data,(void*)&length,sizeof(int)) != 0)
+        {
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+    }
+    return ret;
+}
+
+int _cal_ipc_marshal_int(const int in, pims_ipc_data_h ipc_data)
+{
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(int)) != 0)
+    {
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_marshal_uint(const unsigned int in, pims_ipc_data_h ipc_data)
+{
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(unsigned int)) != 0)
+    {
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_marshal_lli(const long long int in, pims_ipc_data_h ipc_data)
+{
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(long long int)) != 0)
+    {
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_marshal_long(const long in, pims_ipc_data_h ipc_data)
+{
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(long)) != 0)
+    {
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_marshal_double(const double in, pims_ipc_data_h ipc_data)
+{
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (pims_ipc_data_put(ipc_data,(void*)&in,sizeof(double)) != 0)
+    {
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_marshal_caltime(const calendar_time_s in, pims_ipc_data_h ipc_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (pims_ipc_data_put(ipc_data,(void*)&(in.type),sizeof(int)) != 0)
+    {
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    if ( in.type == CALENDAR_TIME_UTIME)
+    {
+        return _cal_ipc_marshal_lli(in.time.utime,ipc_data);
+    }
+    else
+    {
+        ret = _cal_ipc_marshal_int(in.time.date.year,ipc_data);
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+        ret = _cal_ipc_marshal_int(in.time.date.month,ipc_data);
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+        ret = _cal_ipc_marshal_int(in.time.date.mday,ipc_data);
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_marshal_record_common(const cal_record_s* common, pims_ipc_data_h ipc_data)
+{
+
+    retv_if(NULL == common, CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if(pims_ipc_data_put(ipc_data,(void*)&common->type,sizeof(int)) < 0)
+    {
+        return CALENDAR_ERROR_NO_DATA;
+    }
+
+    int length = strlen(common->view_uri);
+    if (pims_ipc_data_put(ipc_data,(void*)common->view_uri,length+1) < 0)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if(pims_ipc_data_put(ipc_data,(void*)&common->properties_max_count,sizeof(int)) < 0)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    if (common->properties_max_count > 0)
+    {
+        if(pims_ipc_data_put(ipc_data,(void*)common->properties_flags,sizeof(char)*common->properties_max_count) < 0)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_NO_DATA;
+        }
+    }
+    if(pims_ipc_data_put(ipc_data,(void*)&common->property_flag,sizeof(char)) < 0)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+/*
+int _cal_ipc_unmarshal_filter(const pims_ipc_data_h ipc_data, calendar_filter_h *filter)
+{
+    cal_composite_filter_s *com_filter = NULL;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    // !! create filter...
+    //calendar_query_create(filter);
+
+    com_filter = (cal_composite_filter_s*)filter;
+
+    return __cal_ipc_unmarshal_composite_filter(ipc_data,com_filter);
+}
+
+int _cal_ipc_marshal_filter(const calendar_filter_h filter, pims_ipc_data_h ipc_data)
+{
+    cal_composite_filter_s *com_filter = NULL;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    com_filter = (cal_composite_filter_s*)filter;
+
+    return __cal_ipc_marshal_composite_filter(com_filter,ipc_data);
+}
+*/
+int _cal_ipc_unmarshal_query(const pims_ipc_data_h ipc_data, calendar_query_h *query)
+{
+    cal_query_s *que = NULL;
+    unsigned int size = 0;
+    char* str = NULL;
+    int count = 0, i = 0;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    // view_uri
+    str = (char*)pims_ipc_data_get(ipc_data,&size);
+
+    ret = calendar_query_create(str, query);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_query_create fail");
+        return ret;
+    }
+
+    que = (cal_query_s *) *query;
+
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        goto ERROR_RETURN;
+    }
+
+    if (count == 0)
+    {
+        que->filter = NULL;
+    }
+    else
+    {
+        calendar_filter_h filter = (calendar_filter_h)que->filter;
+        if (calendar_filter_create(que->view_uri,&filter) != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_filter_create fail");
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+            goto ERROR_RETURN;
+        }
+        que->filter = (cal_composite_filter_s*)filter;
+
+        // for filter_type
+        if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            ret = CALENDAR_ERROR_INVALID_PARAMETER;
+            goto ERROR_RETURN;
+        }
+
+        if (__cal_ipc_unmarshal_composite_filter(ipc_data,que->filter) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            ret = CALENDAR_ERROR_INVALID_PARAMETER;
+            goto ERROR_RETURN;
+        }
+    }
+
+    if (_cal_ipc_unmarshal_int(ipc_data,&(que->projection_count)) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        goto ERROR_RETURN;
+    }
+
+    if (que->projection_count > 0)
+    {
+        que->projection = (unsigned int*)malloc(sizeof(int)*que->projection_count);
+        if (que->projection == NULL)
+        {
+            ERR("malloc fail");
+            ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+            goto ERROR_RETURN;
+        }
+        for(i=0;i<que->projection_count;i++)
+        {
+            if (_cal_ipc_unmarshal_uint(ipc_data,&(que->projection[i])) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_unmarshal fail");
+                ret = CALENDAR_ERROR_INVALID_PARAMETER;
+                goto ERROR_RETURN;
+            }
+        }
+    }
+    else
+    {
+        que->projection = NULL;
+    }
+
+    if (_cal_ipc_unmarshal_int(ipc_data,&(que->sort_property_id)) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        goto ERROR_RETURN;
+    }
+
+    if (_cal_ipc_unmarshal_int(ipc_data,(int*)&(que->asc)) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        goto ERROR_RETURN;
+    }
+
+    que->properties = (cal_property_info_s *)_cal_view_get_property_info(que->view_uri, &que->property_count);
+
+    if (_cal_ipc_unmarshal_int(ipc_data,(int*)&(que->distinct)) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        goto ERROR_RETURN;
+    }
+
+    return CALENDAR_ERROR_NONE;
+
+ERROR_RETURN:
+
+    calendar_query_destroy(*query);
+    *query = NULL;
+
+    return ret;
+}
+
+int _cal_ipc_marshal_query(const calendar_query_h query, pims_ipc_data_h ipc_data)
+{
+    cal_query_s *que = NULL;
+    int i = 0;
+    int length = 0;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER);
+    que = (cal_query_s *)query;
+
+    //view_uri
+    length = strlen(que->view_uri);
+    if (pims_ipc_data_put(ipc_data,(void*)que->view_uri,length+1) < 0)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (que->filter)
+    {
+        if (_cal_ipc_marshal_int(1,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (__cal_ipc_marshal_composite_filter(que->filter,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_marshal_int((que->projection_count),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    for(i=0;i<que->projection_count;i++)
+    {
+        if (_cal_ipc_marshal_uint((que->projection[i]),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_marshal_int((que->sort_property_id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (_cal_ipc_marshal_int((int)(que->asc),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int((int)(que->distinct),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    //properties // property_count
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_ipc_unmarshal_list(const pims_ipc_data_h ipc_data, calendar_list_h* list)
+{
+    int count = 0, i = 0;
+    calendar_record_h record;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (calendar_list_create(list) != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_list_create fail");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+
+    if (_cal_ipc_unmarshal_int(ipc_data,&(count)) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        if (_cal_ipc_unmarshal_record(ipc_data,&record) != CALENDAR_ERROR_NONE )
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            ret = CALENDAR_ERROR_INVALID_PARAMETER;
+            goto ERROR_RETURN;
+        }
+
+        if (calendar_list_add(*list,record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_list_add fail");
+            ret = CALENDAR_ERROR_INVALID_PARAMETER;
+            goto ERROR_RETURN;
+        }
+    }
+
+    calendar_list_first(*list);
+
+    return CALENDAR_ERROR_NONE;
+
+ERROR_RETURN:
+    if (*list)
+    {
+        calendar_list_destroy(*list, true);
+        *list = NULL;
+    }
+
+    return ret;
+}
+
+int _cal_ipc_marshal_list(const calendar_list_h list, pims_ipc_data_h ipc_data)
+{
+    int count = 0, i = 0;
+    calendar_record_h record;
+    retv_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(NULL == ipc_data, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    // count
+    if (calendar_list_get_count(list, &count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_list_get_count fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    calendar_list_first(list);
+
+    for(i=0;i<count;i++)
+    {
+        if (calendar_list_get_current_record_p(list,&record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("calendar_list_get_count fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_record(record,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        calendar_list_next(list);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/ipc/cal_ipc_marshal.h b/common/ipc/cal_ipc_marshal.h
new file mode 100644 (file)
index 0000000..536891c
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CAL_IPC_MARSHAL__
+#define __CAL_IPC_MARSHAL__
+
+#include <pims-ipc-data.h>
+#include "cal_typedef.h"
+#include "cal_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 (*cal_ipc_unmarshal_record_cb)(const pims_ipc_data_h ipc_data, calendar_record_h record);
+typedef int (*cal_ipc_marshal_record_cb)(const calendar_record_h record, pims_ipc_data_h ipc_data);
+typedef int (*cal_ipc_marshal_record_get_primary_id_cb)(const calendar_record_h record, unsigned int *property_id, int *id);
+
+typedef struct {
+    cal_ipc_unmarshal_record_cb unmarshal_record;
+    cal_ipc_marshal_record_cb marshal_record;
+    cal_ipc_marshal_record_get_primary_id_cb get_primary_id;
+} cal_ipc_marshal_record_plugin_cb_s;
+
+int _cal_ipc_unmarshal_record(const pims_ipc_data_h ipc_data, calendar_record_h* precord);
+int _cal_ipc_marshal_record(const calendar_record_h record, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_record_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id);
+
+/*
+ * string
+ * char의 경우 NULL 설정의 이슈로 인하여, [int:string length]+[char*] 로 넘길 수 있도록 설정..
+ */
+int _cal_ipc_unmarshal_char(const pims_ipc_data_h ipc_data, char** ppbufchar);
+int _cal_ipc_unmarshal_int(const pims_ipc_data_h data, int *pout);
+int _cal_ipc_unmarshal_uint(const pims_ipc_data_h data, unsigned int *pout);
+int _cal_ipc_unmarshal_lli(const pims_ipc_data_h data, long long int *pout);
+int _cal_ipc_unmarshal_long(const pims_ipc_data_h data, long *pout);
+int _cal_ipc_unmarshal_double(const pims_ipc_data_h data, double *pout);
+int _cal_ipc_unmarshal_caltime(const pims_ipc_data_h data, calendar_time_s *pout);
+int _cal_ipc_unmarshal_record_common(const pims_ipc_data_h ipc_data, cal_record_s* common);
+
+/*
+ * NULL 이슈로 _cal_ipc_unmarshal_char / _cal_ipc_marshal_char 는 pair 를 이루어야함.
+ */
+int _cal_ipc_marshal_char(const char* bufchar, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_int(const int in, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_uint(const unsigned int in, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_lli(const long long int in, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_long(const long in, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_double(const double in, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_caltime(const calendar_time_s in, pims_ipc_data_h ipc_data);
+int _cal_ipc_marshal_record_common(const cal_record_s* common, pims_ipc_data_h ipc_data);
+
+/*
+ * filter, query
+ *
+ * marsharl : view_uri + other
+ * unmarshal : view_uri를 먼저 get 하고 난 이후 나머지를 ..
+ */
+//int _cal_ipc_unmarshal_filter(const pims_ipc_data_h ipc_data, calendar_filter_h *filter);
+//int _cal_ipc_marshal_filter(const calendar_filter_h filter, pims_ipc_data_h ipc_data);
+int _cal_ipc_unmarshal_query(const pims_ipc_data_h ipc_data, calendar_query_h *query);
+int _cal_ipc_marshal_query(const calendar_query_h query, pims_ipc_data_h ipc_data);
+int _cal_ipc_unmarshal_list(const pims_ipc_data_h ipc_data, calendar_list_h *list);
+int _cal_ipc_marshal_list(const calendar_list_h list, pims_ipc_data_h ipc_data);
+
+
+/*
+ * for property_id
+ */
+
+#define CAL_IPC_CHECK_PROPERTIES_FLAG(src) (CAL_IPC_CHECK_PROJECTION(src) || CAL_IPC_CHECK_DIRTY(src))
+#define CAL_IPC_CHECK_PROJECTION(src) ((src) & (unsigned char)CAL_PROPERTY_FLAG_PROJECTION)
+#define CAL_IPC_CHECK_DIRTY(src) ((src) & (unsigned char)CAL_PROPERTY_FLAG_DIRTY)
+
+#endif /* __CAL_IPC_MARSHAL__ */
diff --git a/common/ipc/cal_ipc_marshal_alarm.c b/common/ipc/cal_ipc_marshal_alarm.c
new file mode 100644 (file)
index 0000000..60a96af
--- /dev/null
@@ -0,0 +1,207 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+
+static int __cal_ipc_unmarshal_alarm(const pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_alarm(const calendar_record_h record, pims_ipc_data_h ipc_data);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_alarm_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_alarm,
+        .marshal_record = __cal_ipc_marshal_alarm,
+        .get_primary_id = NULL
+};
+
+static int __cal_ipc_unmarshal_alarm(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_alarm_s* palarm = NULL;
+    bool bpropertyflag = false;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(record==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    palarm = (cal_alarm_s*) record;
+
+    if (palarm->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&palarm->alarm_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&palarm->event_id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&palarm->alarm_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_unmarshal_int(ipc_data,&palarm->is_deleted) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&palarm->alarm_time) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&palarm->remind_tick) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&palarm->remind_tick_unit) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&palarm->alarm_tone) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&palarm->alarm_description) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_alarm(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_alarm_s* palarm = (cal_alarm_s*) record;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(palarm==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (_cal_ipc_marshal_record_common(&(palarm->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (palarm->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_int((palarm->alarm_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((palarm->event_id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_marshal_int((palarm->alarm_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (_cal_ipc_marshal_int((palarm->is_deleted),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_lli((palarm->alarm_time),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_int((palarm->remind_tick),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_int((palarm->remind_tick_unit),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((palarm->alarm_tone),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(palarm->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_char((palarm->alarm_description),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/ipc/cal_ipc_marshal_attendee.c b/common/ipc/cal_ipc_marshal_attendee.c
new file mode 100644 (file)
index 0000000..f08ed50
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+
+static int __cal_ipc_unmarshal_attendee(const pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_attendee(const calendar_record_h record, pims_ipc_data_h ipc_data);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_attendee_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_attendee,
+        .marshal_record = __cal_ipc_marshal_attendee,
+        .get_primary_id = NULL
+};
+
+static int __cal_ipc_unmarshal_attendee(const pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_attendee_s* pattendee = NULL;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(record==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    pattendee = (cal_attendee_s*) record;
+
+    if (pattendee->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&pattendee->event_id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pattendee->attendee_number) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pattendee->attendee_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pattendee->attendee_ct_index) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pattendee->attendee_uid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pattendee->attendee_group) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pattendee->attendee_email) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pattendee->attendee_role) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pattendee->attendee_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pattendee->attendee_rsvp) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pattendee->attendee_delegate_uri) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pattendee->attendee_delegator_uri) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pattendee->attendee_name) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_attendee(const calendar_record_h record, pims_ipc_data_h ipc_data )
+{
+    cal_attendee_s* pattendee = (cal_attendee_s*) record;
+    bool bpropertyflag = false;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(pattendee==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (_cal_ipc_marshal_record_common(&(pattendee->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (pattendee->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((pattendee->event_id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_marshal_char((pattendee->attendee_number),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_int((pattendee->attendee_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_int((pattendee->attendee_ct_index),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_char((pattendee->attendee_uid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((pattendee->attendee_group),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_char((pattendee->attendee_email),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_int((pattendee->attendee_role),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_marshal_int((pattendee->attendee_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_marshal_int((pattendee->attendee_rsvp),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_marshal_char((pattendee->attendee_delegate_uri),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_marshal_char((pattendee->attendee_delegator_uri),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pattendee->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_marshal_char((pattendee->attendee_name),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/ipc/cal_ipc_marshal_calendar.c b/common/ipc/cal_ipc_marshal_calendar.c
new file mode 100644 (file)
index 0000000..bd793d4
--- /dev/null
@@ -0,0 +1,323 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_calendar(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_calendar(const calendar_record_h record, pims_ipc_data_h ipc_data);
+static int __cal_ipc_marshal_calendar_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_calendar_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_calendar,
+        .marshal_record = __cal_ipc_marshal_calendar,
+        .get_primary_id = __cal_ipc_marshal_calendar_get_primary_id
+};
+
+static int __cal_ipc_unmarshal_calendar(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_calendar_s* pcalendar = NULL;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    pcalendar = (cal_calendar_s*) record;
+
+    if (pcalendar->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&pcalendar->index) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pcalendar->store_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->uid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_unmarshal_long(ipc_data,&pcalendar->updated) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->name) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->description) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->color) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->location) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pcalendar->visibility) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pcalendar->sync_event) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pcalendar->is_deleted) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pcalendar->account_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->sync_data1) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->sync_data2) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->sync_data3) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pcalendar->sync_data4) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_calendar(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_calendar_s* pcalendar = (cal_calendar_s*)record;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(pcalendar==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(pcalendar->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (pcalendar->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((pcalendar->index),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_marshal_int((pcalendar->store_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->uid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (_cal_ipc_marshal_long((pcalendar->updated),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->name),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->description),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->color),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->location),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_int((pcalendar->visibility),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_marshal_int((pcalendar->sync_event),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_marshal_int((pcalendar->is_deleted),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_marshal_int((pcalendar->account_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->sync_data1),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->sync_data2),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->sync_data3),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pcalendar->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_marshal_char((pcalendar->sync_data4),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_calendar_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id)
+{
+    *property_id = CAL_PROPERTY_CALENDAR_ID;
+    return calendar_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/cal_ipc_marshal_event.c b/common/ipc/cal_ipc_marshal_event.c
new file mode 100644 (file)
index 0000000..127f361
--- /dev/null
@@ -0,0 +1,1172 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_event(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_event(const calendar_record_h record, pims_ipc_data_h ipc_data);
+static int __cal_ipc_marshal_event_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_event_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_event,
+        .marshal_record = __cal_ipc_marshal_event,
+        .get_primary_id = __cal_ipc_marshal_event_get_primary_id
+};
+
+static int __cal_ipc_unmarshal_event(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_event_s *pevent = NULL;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    pevent = (cal_event_s*) record;
+
+    if (pevent->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&pevent->index) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->calendar_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->summary) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->description) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->location) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->categories) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->exdate) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&pevent->event_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&pevent->priority) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->timezone) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->contact_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->busy_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->sensitivity) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->meeting_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->uid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->organizer_name) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->organizer_email) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&pevent->original_event_id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[18]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&pevent->latitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[19]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&pevent->longitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[20]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->email_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[21]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pevent->created_time) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[23]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->is_deleted) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[22]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pevent->last_mod) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[24]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->freq) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[25]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->range_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[26]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->until_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pevent->until_utime) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->until_year) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->until_month) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->until_mday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[27]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->count) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[28]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->interval) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[29]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->bysecond) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[30]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->byminute) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[31]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->byhour) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[32]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->byday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[33]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->bymonthday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[34]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->byyearday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[35]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->byweekno) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[36]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->bymonth) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[37]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->bysetpos) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[38]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->wkst) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[39]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->recurrence_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[40]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->rdate) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[41]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->has_attendee) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[42]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->has_alarm) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[51]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pevent->system_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_unmarshal_long(ipc_data,&pevent->updated) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[43]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->sync_data1) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[44]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->sync_data2) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[45]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->sync_data3) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[46]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->sync_data4) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[47]) )
+    {
+        if (_cal_ipc_unmarshal_caltime(ipc_data,&pevent->start) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[52]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->start_tzid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[48]) )
+    {
+        if (_cal_ipc_unmarshal_caltime(ipc_data,&pevent->end) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[53]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pevent->end_tzid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    // !! alarm_list, attendee_list
+    // alarm_list
+    int count = 0, i = 0;
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        calendar_record_h alarm_child_record = NULL;
+        if (_cal_ipc_unmarshal_record(ipc_data, &alarm_child_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        pevent->alarm_list = g_list_append(pevent->alarm_list, alarm_child_record);
+    }
+
+    // attendee_list
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        calendar_record_h attendee_child_record = NULL;
+        if (_cal_ipc_unmarshal_record(ipc_data, &attendee_child_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        pevent->attendee_list = g_list_append(pevent->attendee_list, attendee_child_record);
+    }
+
+    // exception_list
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        calendar_record_h exception_child_record = NULL;
+        if (_cal_ipc_unmarshal_record(ipc_data, &exception_child_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        pevent->exception_list = g_list_append(pevent->exception_list, exception_child_record);
+    }
+
+    // extended_list
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        calendar_record_h child_record = NULL;
+        if (_cal_ipc_unmarshal_record(ipc_data, &child_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        pevent->extended_list = g_list_append(pevent->extended_list, child_record);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_event(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_event_s* pevent = (cal_event_s*) record;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(pevent==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(pevent->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (pevent->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((pevent->index),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->calendar_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->summary),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->description),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->location),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->categories),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->exdate),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->event_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->priority),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->timezone),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->contact_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->busy_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->sensitivity),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->meeting_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->uid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->organizer_name),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->organizer_email),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((pevent->original_event_id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[18]) )
+    {
+        if (_cal_ipc_marshal_double((pevent->latitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[19]) )
+    {
+        if (_cal_ipc_marshal_double((pevent->longitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[20]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->email_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[21]) )
+    {
+        if (_cal_ipc_marshal_lli((pevent->created_time),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[23]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->is_deleted),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[22]) )
+    {
+        if (_cal_ipc_marshal_lli((pevent->last_mod),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[24]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->freq),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[25]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->range_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[26]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->until_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_lli((pevent->until_utime),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pevent->until_year),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pevent->until_month),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pevent->until_mday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[27]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->count),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[28]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->interval),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[29]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->bysecond),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[30]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->byminute),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[31]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->byhour),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[32]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->byday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[33]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->bymonthday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[34]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->byyearday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[35]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->byweekno),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[36]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->bymonth),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[37]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->bysetpos),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[38]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->wkst),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[39]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->recurrence_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[40]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->rdate),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[41]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->has_attendee),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[42]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->has_alarm),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[51]) )
+    {
+        if (_cal_ipc_marshal_int((pevent->system_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_marshal_long((pevent->updated),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[43]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->sync_data1),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[44]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->sync_data2),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[45]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->sync_data3),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[46]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->sync_data4),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[47]) )
+    {
+        if (_cal_ipc_marshal_caltime((pevent->start),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[52]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->start_tzid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[48]) )
+    {
+        if (_cal_ipc_marshal_caltime((pevent->end),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pevent->common.properties_flags[53]) )
+    {
+        if (_cal_ipc_marshal_char((pevent->end_tzid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    // !! alarm_list, attendee_list
+    // alarm_list
+    if (pevent->alarm_list)
+    {
+        int count = g_list_length(pevent->alarm_list);
+        GList *cursor = g_list_first(pevent->alarm_list);
+        calendar_record_h alarm_child_record;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            alarm_child_record = (calendar_record_h)cursor->data;
+            if (alarm_child_record == NULL)
+            {
+                cursor = g_list_next(cursor);
+                continue;
+            }
+            if (_cal_ipc_marshal_record(alarm_child_record, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_list_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (pevent->attendee_list)
+    {
+        int count = g_list_length(pevent->attendee_list);
+        GList *cursor = g_list_first(pevent->attendee_list);
+        calendar_record_h attendee_child_record;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            attendee_child_record = (calendar_record_h)cursor->data;
+            if (attendee_child_record == NULL)
+            {
+                cursor = g_list_next(cursor);
+                continue;
+            }
+            if (_cal_ipc_marshal_record(attendee_child_record, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_list_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (pevent->exception_list)
+    {
+        int count = g_list_length(pevent->exception_list);
+        GList *cursor = g_list_first(pevent->exception_list);
+        calendar_record_h child_record;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            child_record = (calendar_record_h)cursor->data;
+            if (child_record == NULL)
+            {
+                cursor = g_list_next(cursor);
+                continue;
+            }
+            if (_cal_ipc_marshal_record(child_record, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_list_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (pevent->extended_list)
+    {
+        int count = g_list_length(pevent->extended_list);
+        GList *cursor = g_list_first(pevent->extended_list);
+        calendar_record_h child_record;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            child_record = (calendar_record_h)cursor->data;
+            if (child_record == NULL)
+            {
+                cursor = g_list_next(cursor);
+                continue;
+            }
+            if (_cal_ipc_marshal_record(child_record, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_list_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_event_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id)
+{
+    *property_id = CAL_PROPERTY_EVENT_ID;
+    return calendar_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/cal_ipc_marshal_extended.c b/common/ipc/cal_ipc_marshal_extended.c
new file mode 100644 (file)
index 0000000..180cee2
--- /dev/null
@@ -0,0 +1,152 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_extended(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_extended(const calendar_record_h record, pims_ipc_data_h ipc_data);
+static int __cal_ipc_marshal_extended_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_extended_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_extended,
+        .marshal_record = __cal_ipc_marshal_extended,
+        .get_primary_id = __cal_ipc_marshal_extended_get_primary_id
+};
+
+static int __cal_ipc_unmarshal_extended(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_extended_s* pextended = NULL;
+    bool bpropertyflag = false;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    pextended = (cal_extended_s*) record;
+
+    if (pextended->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&pextended->id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pextended->record_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pextended->record_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pextended->key) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pextended->value) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_extended(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_extended_s* pextended = (cal_extended_s*) record;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(pextended==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(pextended->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (pextended->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((pextended->id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_int((pextended->record_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_int((pextended->record_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_char((pextended->key),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pextended->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((pextended->value),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_extended_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id)
+{
+    *property_id = CAL_PROPERTY_EXTENDED_ID;
+    return calendar_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/cal_ipc_marshal_instance_allday.c b/common/ipc/cal_ipc_marshal_instance_allday.c
new file mode 100644 (file)
index 0000000..970e951
--- /dev/null
@@ -0,0 +1,403 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_instance_allday(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_instance_allday(const calendar_record_h record, pims_ipc_data_h ipc_data);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_instance_allday_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_instance_allday,
+        .marshal_record = __cal_ipc_marshal_instance_allday,
+        .get_primary_id = NULL
+};
+
+static int __cal_ipc_unmarshal_instance_allday(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    bool bpropertyflag = false;
+
+    cal_instance_allday_s* pinstanceallday = NULL;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    pinstanceallday = (cal_instance_allday_s*) record;
+
+    if (pinstanceallday->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->event_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->calendar_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtstart_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtstart_year) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtstart_month) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtstart_mday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtend_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtend_year) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtend_month) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->dtend_mday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pinstanceallday->summary) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pinstanceallday->description) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pinstanceallday->location) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->busy_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->event_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->priority) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[10]) )
+    {
+    if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->sensitivity) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->has_rrule) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&pinstanceallday->latitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&pinstanceallday->longitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->has_alarm) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstanceallday->original_event_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pinstanceallday->last_mod) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_instance_allday(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_instance_allday_s* pinstanceallday = (cal_instance_allday_s*) record;
+    bool bpropertyflag = false;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(pinstanceallday==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(pinstanceallday->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (pinstanceallday->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->event_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->calendar_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->dtstart_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pinstanceallday->dtstart_year),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pinstanceallday->dtstart_month),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pinstanceallday->dtstart_mday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->dtend_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pinstanceallday->dtend_year),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pinstanceallday->dtend_month),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((pinstanceallday->dtend_mday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_char((pinstanceallday->summary),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_char((pinstanceallday->description),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((pinstanceallday->location),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->busy_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->event_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->priority),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->sensitivity),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->has_rrule),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_marshal_double((pinstanceallday->latitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_marshal_double((pinstanceallday->longitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->has_alarm),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_marshal_int((pinstanceallday->original_event_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstanceallday->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_marshal_lli((pinstanceallday->last_mod),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/ipc/cal_ipc_marshal_instance_normal.c b/common/ipc/cal_ipc_marshal_instance_normal.c
new file mode 100644 (file)
index 0000000..f983d3e
--- /dev/null
@@ -0,0 +1,364 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_instance_normal(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_instance_normal(const calendar_record_h record, pims_ipc_data_h ipc_data);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_instance_normal_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_instance_normal,
+        .marshal_record = __cal_ipc_marshal_instance_normal,
+        .get_primary_id = NULL
+};
+
+static int __cal_ipc_unmarshal_instance_normal(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    bool bpropertyflag = false;
+
+    cal_instance_normal_s* pinstancenormal = NULL;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    pinstancenormal = (cal_instance_normal_s*) record;
+
+    if (pinstancenormal->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->event_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->calendar_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->dtstart_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pinstancenormal->dtstart_utime) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->dtend_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pinstancenormal->dtend_utime) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pinstancenormal->summary) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pinstancenormal->description) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pinstancenormal->location) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->busy_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->event_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->priority) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->sensitivity) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->has_rrule) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&pinstancenormal->latitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&pinstancenormal->longitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->has_alarm) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pinstancenormal->original_event_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pinstancenormal->last_mod) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_instance_normal(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_instance_normal_s* pinstancenormal = (cal_instance_normal_s*) record;
+    bool bpropertyflag = false;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(pinstancenormal==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(pinstancenormal->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (pinstancenormal->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[0]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->event_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->calendar_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->dtstart_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_lli((pinstancenormal->dtstart_utime),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->dtend_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_lli((pinstancenormal->dtend_utime),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_char((pinstancenormal->summary),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_char((pinstancenormal->description),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((pinstancenormal->location),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->busy_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->event_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->priority),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->sensitivity),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->has_rrule),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_marshal_double((pinstancenormal->latitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_marshal_double((pinstancenormal->longitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->has_alarm),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_marshal_int((pinstancenormal->original_event_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(pinstancenormal->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_marshal_lli((pinstancenormal->last_mod),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/ipc/cal_ipc_marshal_search.c b/common/ipc/cal_ipc_marshal_search.c
new file mode 100644 (file)
index 0000000..0c62056
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_search(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_search(const calendar_record_h record, pims_ipc_data_h ipc_data);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_search_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_search,
+        .marshal_record = __cal_ipc_marshal_search,
+        .get_primary_id = NULL
+};
+
+static int __cal_ipc_unmarshal_search_value(pims_ipc_data_h ipc_data, cal_search_value_s* pvalue);
+static int __cal_ipc_marshal_search_value(const cal_search_value_s* pvalue, pims_ipc_data_h ipc_data);
+
+static int __cal_ipc_unmarshal_search(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_search_s* psearch = NULL;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(record==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    psearch = (cal_search_s*) record;
+
+    int count = 0,i = 0;
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    for(i=0;i<count;i++)
+    {
+        cal_search_value_s* value_data = NULL;
+        value_data = calloc(1, sizeof(cal_search_value_s));
+        if (value_data == NULL)
+        {
+            ERR("calloc fail");
+            return CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+
+        if (__cal_ipc_unmarshal_search_value(ipc_data, value_data) != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(value_data);
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        psearch->values = g_slist_append(psearch->values, value_data);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_search(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_search_s* psearch = (cal_search_s*) record;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+    retv_if(psearch==NULL,CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (_cal_ipc_marshal_record_common(&(psearch->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (psearch->values)
+    {
+        int count = g_slist_length(psearch->values);
+        GSList *cursor = psearch->values;
+        cal_search_value_s* value_data;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            value_data = (cal_search_value_s *)cursor->data;
+            if (value_data == NULL)
+            {
+                cursor = g_slist_next(cursor);
+                continue;
+            }
+            if (__cal_ipc_marshal_search_value((const cal_search_value_s*)value_data, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_slist_next(cursor);
+        }
+
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_unmarshal_search_value(pims_ipc_data_h ipc_data, cal_search_value_s* pvalue)
+{
+    if (_cal_ipc_unmarshal_int(ipc_data,&pvalue->property_id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_STR) == true)
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&pvalue->value.s) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_INT) == true)
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&pvalue->value.i) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&pvalue->value.d) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_LLI) == true)
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&pvalue->value.lli) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+    {
+        if (_cal_ipc_unmarshal_caltime(ipc_data,&pvalue->value.caltime) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else
+    {
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",pvalue->property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_search_value(const cal_search_value_s* pvalue, pims_ipc_data_h ipc_data)
+{
+    if (_cal_ipc_marshal_int(pvalue->property_id,ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_STR) == true)
+    {
+        if (_cal_ipc_marshal_char(pvalue->value.s,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_INT) == true)
+    {
+        if (_cal_ipc_marshal_int(pvalue->value.i,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+    {
+        if (_cal_ipc_marshal_double(pvalue->value.d,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_LLI) == true)
+    {
+        if (_cal_ipc_marshal_lli(pvalue->value.lli,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(pvalue->property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+    {
+        if (_cal_ipc_marshal_caltime(pvalue->value.caltime,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else
+    {
+        ASSERT_NOT_REACHED("invalid parameter (property:%d)",pvalue->property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/common/ipc/cal_ipc_marshal_timezone.c b/common/ipc/cal_ipc_marshal_timezone.c
new file mode 100644 (file)
index 0000000..6a5e64d
--- /dev/null
@@ -0,0 +1,312 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_timezone(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_timezone(const calendar_record_h record, pims_ipc_data_h ipc_data);
+static int __cal_ipc_marshal_timezone_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_timezone_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_timezone,
+        .marshal_record = __cal_ipc_marshal_timezone,
+        .get_primary_id = __cal_ipc_marshal_timezone_get_primary_id
+};
+
+static int __cal_ipc_unmarshal_timezone(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_timezone_s* ptimezone = NULL;
+    bool bpropertyflag = false;
+
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    ptimezone = (cal_timezone_s*) record;
+
+    if (ptimezone->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->index) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->tz_offset_from_gmt) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptimezone->standard_name) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->std_start_month) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->std_start_position_of_week) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->std_start_day) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->std_start_hour) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->standard_bias) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptimezone->day_light_name) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->day_light_start_month) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->day_light_start_position_of_week) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->day_light_start_day) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->day_light_start_hour) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->day_light_bias) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptimezone->calendar_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_timezone(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_timezone_s* ptimezone = (cal_timezone_s*) record;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(ptimezone==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(ptimezone->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (ptimezone->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((ptimezone->index),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->tz_offset_from_gmt),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_char((ptimezone->standard_name),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->std_start_month),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->std_start_position_of_week),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->std_start_day),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->std_start_hour),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->standard_bias),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_marshal_char((ptimezone->day_light_name),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->day_light_start_month),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->day_light_start_position_of_week),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->day_light_start_day),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->day_light_start_hour),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->day_light_bias),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptimezone->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_marshal_int((ptimezone->calendar_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_timezone_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id)
+{
+    *property_id = CAL_PROPERTY_TIMEZONE_ID;
+    return calendar_record_get_int(record, *property_id, id );
+}
diff --git a/common/ipc/cal_ipc_marshal_todo.c b/common/ipc/cal_ipc_marshal_todo.c
new file mode 100644 (file)
index 0000000..df7a1cb
--- /dev/null
@@ -0,0 +1,994 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+#include "cal_view.h"
+
+static int __cal_ipc_unmarshal_todo(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_todo(const calendar_record_h record, pims_ipc_data_h ipc_data);
+static int __cal_ipc_marshal_todo_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_todo_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_todo,
+        .marshal_record = __cal_ipc_marshal_todo,
+        .get_primary_id = __cal_ipc_marshal_todo_get_primary_id
+};
+
+static int __cal_ipc_unmarshal_todo(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_todo_s* ptodo = NULL;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    ptodo = (cal_todo_s*) record;
+
+    if (ptodo->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->index) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->calendar_id) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->summary) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->description) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->location) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->categories) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&ptodo->todo_status) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,(int*)&ptodo->priority) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->sensitivity) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->uid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&ptodo->latitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_unmarshal_double(ipc_data,&ptodo->longitude) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&ptodo->created_time) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&ptodo->completed_time) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->progress) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->is_deleted) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_unmarshal_lli(ipc_data,&ptodo->last_mod) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[17]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->freq) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[18]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->range_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[19]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->until_type) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_lli(ipc_data,&ptodo->until_utime) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->until_year) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->until_month) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->until_mday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[20]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->count) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[21]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->interval) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[22]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->bysecond) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[23]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->byminute) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[24]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->byhour) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[25]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->byday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[26]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->bymonthday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[27]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->byyearday) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[28]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->byweekno) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[29]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->bymonth) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[30]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->bysetpos) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[31]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->wkst) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[32]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->has_alarm) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_unmarshal_long(ipc_data,&ptodo->updated) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[33]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->sync_data1) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[34]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->sync_data2) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[35]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->sync_data3) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[36]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->sync_data4) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[37]) )
+    {
+        if (_cal_ipc_unmarshal_caltime(ipc_data,&ptodo->start) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[40]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->start_tzid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[38]) )
+    {
+        if (_cal_ipc_unmarshal_caltime(ipc_data,&ptodo->due) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[41]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->due_tzid) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[42]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->organizer_name) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[43]) )
+    {
+        if (_cal_ipc_unmarshal_char(ipc_data,&ptodo->organizer_email) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[44]) )
+    {
+        if (_cal_ipc_unmarshal_int(ipc_data,&ptodo->has_attendee) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    // !! alarm_list
+    int count = 0, i = 0;
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        calendar_record_h alarm_child_record = NULL;
+
+        if (_cal_ipc_unmarshal_record(ipc_data, &alarm_child_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        ptodo->alarm_list = g_list_append(ptodo->alarm_list, alarm_child_record);
+    }
+
+    // attendee_list
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        calendar_record_h attendee_child_record = NULL;
+        if (_cal_ipc_unmarshal_record(ipc_data, &attendee_child_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        ptodo->attendee_list = g_list_append(ptodo->attendee_list, attendee_child_record);
+    }
+
+    //extended
+    if (_cal_ipc_unmarshal_int(ipc_data,&count) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    for(i=0;i<count;i++)
+    {
+        calendar_record_h child_record = NULL;
+        if (_cal_ipc_unmarshal_record(ipc_data, &child_record) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        ptodo->extended_list = g_list_append(ptodo->extended_list, child_record);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_todo(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_todo_s* ptodo = (cal_todo_s*)record;
+    bool bpropertyflag = false;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(ptodo==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(ptodo->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (ptodo->common.properties_max_count > 0)
+    {
+        bpropertyflag = true;
+    }
+    // read only or primary/secondary key
+    if (_cal_ipc_marshal_int((ptodo->index),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[1]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->calendar_id),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[2]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->summary),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[3]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->description),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[4]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->location),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[5]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->categories),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[6]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->todo_status),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[7]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->priority),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[8]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->sensitivity),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[9]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->uid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[10]) )
+    {
+        if (_cal_ipc_marshal_double((ptodo->latitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[11]) )
+    {
+        if (_cal_ipc_marshal_double((ptodo->longitude),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[13]) )
+    {
+        if (_cal_ipc_marshal_lli((ptodo->created_time),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[15]) )
+    {
+        if (_cal_ipc_marshal_lli((ptodo->completed_time),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[12]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->progress),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[16]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->is_deleted),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[14]) )
+    {
+        if (_cal_ipc_marshal_lli((ptodo->last_mod),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[17]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->freq),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[18]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->range_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[19]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->until_type),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_lli((ptodo->until_utime),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((ptodo->until_year),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((ptodo->until_month),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        if (_cal_ipc_marshal_int((ptodo->until_mday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[20]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->count),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[21]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->interval),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[22]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->bysecond),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[23]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->byminute),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[24]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->byhour),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[25]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->byday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[26]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->bymonthday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[27]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->byyearday),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[28]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->byweekno),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[29]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->bymonth),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[30]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->bysetpos),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[31]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->wkst),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[32]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->has_alarm),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (_cal_ipc_marshal_long((ptodo->updated),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[33]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->sync_data1),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[34]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->sync_data2),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[35]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->sync_data3),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[36]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->sync_data4),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[37]) )
+    {
+        if (_cal_ipc_marshal_caltime((ptodo->start),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[40]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->start_tzid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[38]) )
+    {
+        if (_cal_ipc_marshal_caltime((ptodo->due),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[41]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->due_tzid),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[42]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->organizer_name),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[43]) )
+    {
+        if (_cal_ipc_marshal_char((ptodo->organizer_email),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    if (bpropertyflag == false || CAL_IPC_CHECK_PROPERTIES_FLAG(ptodo->common.properties_flags[44]) )
+    {
+        if (_cal_ipc_marshal_int((ptodo->has_attendee),ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    // !! alarm_list
+    if (ptodo->alarm_list)
+    {
+        int count = g_list_length(ptodo->alarm_list);
+        GList *cursor = g_list_first(ptodo->alarm_list);
+        calendar_record_h alarm_child_record;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            alarm_child_record = (calendar_record_h)cursor->data;
+            if (alarm_child_record == NULL)
+            {
+                cursor = g_list_next(cursor);
+                continue;
+            }
+            if (_cal_ipc_marshal_record(alarm_child_record, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_list_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (ptodo->attendee_list)
+    {
+        int count = g_list_length(ptodo->attendee_list);
+        GList *cursor = g_list_first(ptodo->attendee_list);
+        calendar_record_h attendee_child_record;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            attendee_child_record = (calendar_record_h)cursor->data;
+            if (attendee_child_record == NULL)
+            {
+                cursor = g_list_next(cursor);
+                continue;
+            }
+            if (_cal_ipc_marshal_record(attendee_child_record, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_list_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    if (ptodo->extended_list)
+    {
+        int count = g_list_length(ptodo->extended_list);
+        GList *cursor = g_list_first(ptodo->extended_list);
+        calendar_record_h child_record;
+
+        if (_cal_ipc_marshal_int(count,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+        while (cursor)
+        {
+            child_record = (calendar_record_h)cursor->data;
+            if (child_record == NULL)
+            {
+                cursor = g_list_next(cursor);
+                continue;
+            }
+            if (_cal_ipc_marshal_record(child_record, ipc_data) != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_marshal fail");
+                return CALENDAR_ERROR_INVALID_PARAMETER;
+            }
+            cursor = g_list_next(cursor);
+        }
+    }
+    else
+    {
+        if (_cal_ipc_marshal_int(0,ipc_data) != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_todo_get_primary_id(const calendar_record_h record, unsigned int *property_id, int *id)
+{
+    *property_id = CAL_PROPERTY_TODO_ID;
+    return calendar_record_get_int(record, *property_id, id );
+}
+
diff --git a/common/ipc/cal_ipc_marshal_updated_info.c b/common/ipc/cal_ipc_marshal_updated_info.c
new file mode 100644 (file)
index 0000000..be1f862
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "cal_internal.h"
+#include "cal_ipc_marshal.h"
+
+static int __cal_ipc_unmarshal_updated_info(pims_ipc_data_h ipc_data, calendar_record_h record);
+static int __cal_ipc_marshal_updated_info(const calendar_record_h record, pims_ipc_data_h ipc_data);
+
+cal_ipc_marshal_record_plugin_cb_s _cal_ipc_record_updated_info_plugin_cb = {
+        .unmarshal_record = __cal_ipc_unmarshal_updated_info,
+        .marshal_record = __cal_ipc_marshal_updated_info,
+        .get_primary_id = NULL
+};
+
+static int __cal_ipc_unmarshal_updated_info(pims_ipc_data_h ipc_data, calendar_record_h record)
+{
+    cal_updated_info_s* pupdatedinfo = NULL;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(record==NULL,CALENDAR_ERROR_NO_DATA);
+
+    pupdatedinfo = (cal_updated_info_s*) record;
+
+    if (_cal_ipc_unmarshal_int(ipc_data,&pupdatedinfo->type) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_unmarshal_int(ipc_data,&pupdatedinfo->id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_unmarshal_int(ipc_data,&pupdatedinfo->calendar_id) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_unmarshal_int(ipc_data,&pupdatedinfo->version) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_unmarshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_ipc_marshal_updated_info(const calendar_record_h record, pims_ipc_data_h ipc_data)
+{
+    cal_updated_info_s* pupdatedinfo = (cal_updated_info_s*) record;
+    retv_if(ipc_data==NULL,CALENDAR_ERROR_NO_DATA);
+    retv_if(pupdatedinfo==NULL,CALENDAR_ERROR_NO_DATA);
+
+    if (_cal_ipc_marshal_record_common(&(pupdatedinfo->common),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int((pupdatedinfo->type),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int((pupdatedinfo->id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int((pupdatedinfo->calendar_id),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    if (_cal_ipc_marshal_int((pupdatedinfo->version),ipc_data) != CALENDAR_ERROR_NONE)
+    {
+        ERR("_cal_ipc_marshal fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/dft/CMakeLists.txt b/dft/CMakeLists.txt
new file mode 100644 (file)
index 0000000..af0e47f
--- /dev/null
@@ -0,0 +1,53 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(dft-calendar C)
+
+SET(TC_SRCS
+       ./src/dft_main.c
+       ./src/dft_util.c
+       )
+
+SET(PREFIX "/usr")
+SET(BINDIR "${PREFIX}/bin")
+SET(OPTDIR "/usr/share/calendar-svc")
+
+SET(LIBNAME calendar-service-native)
+
+IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+       SET(CMAKE_BUILD_TYPE "Release")
+ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "")
+MESSAGE("Build type: ${CMAKE_BUILD_TYPE}")
+
+INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+LINK_DIRECTORIES(${CMAKE_SOURCE_DIR}/api)
+LINK_DIRECTORIES(${CMAKE_SOURCE_DIR})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(tc_pkgs REQUIRED
+       dlog
+       glib-2.0
+       )
+
+FOREACH(flag ${tc_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+SET(CMAKE_C_FLAGS_RELEASE "-O2")
+
+FIND_PROGRAM(UNAME NAMES uname)
+EXEC_PROGRAM("${UNAME}" ARGS "-m" OUTPUT_VARIABLE "ARCH")
+IF("${ARCH}" STREQUAL "arm")
+       ADD_DEFINITIONS("-DTARGET")
+       MESSAGE("add -DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DTC_LOG_PRINTF")
+SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
+
+ADD_EXECUTABLE(${PROJECT_NAME} ${TC_SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${tc_pkgs_LDFLAGS} ${LIBNAME})
+
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${OPTDIR})
+
diff --git a/dft/src/dft_main.c b/dft/src/dft_main.c
new file mode 100644 (file)
index 0000000..5868799
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdlib.h>
+#include <stdio.h>
+#include <calendar2.h>
+
+#include "dft_util.h"
+
+#define MAX_COLS 32768
+
+static void __dft_calendar_help(void)
+{
+       printf("usage: dft-calendar path(string) count(int)\n"
+                       "eg. dft-calendar \"./calendar.txt\" 10\n");
+}
+
+// get type depending on file name.
+static int __dft_get_file_type(char *path)
+{
+       char *p, *q = NULL;
+       char dl = '/';
+
+       q = p = path;
+       while (*p)
+       {
+               if (*p == dl)
+               {
+                       q = p;
+               }
+               p++;
+       }
+       if (strstr(q, "event") || strstr(q, "schedule"))
+       {
+               return CALENDAR_BOOK_TYPE_EVENT;
+       }
+       else if (strstr(q, "todo") || strstr(q, "task"))
+       {
+               return CALENDAR_BOOK_TYPE_TODO;
+       }
+       else
+       {
+               printf("set default type\n");
+               return CALENDAR_BOOK_TYPE_EVENT;
+       }
+       return -1;
+}
+
+static int  __dft_event_set_1(calendar_record_h event, int book_id, char *subject, char *location)
+{
+       int ret;
+
+       ret = calendar_record_set_int(event, _calendar_event.calendar_book_id, book_id);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_event.calendar_book_id\n");
+               return -1;
+       }
+       ret = calendar_record_set_str(event, _calendar_event.summary, subject);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_event.summary\n");
+               return -1;
+       }
+       ret = calendar_record_set_str(event, _calendar_event.location, location);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_event.location\n");
+               return -1;
+       }
+       return 0;
+}
+
+static int __dft_event_set_2(calendar_record_h event, char *allday, char *sdate, char *stime, char *edate, char *etime)
+{
+       int ret;
+       int y, m, d;
+       calendar_time_s st = {0}, et = {0};
+
+       if (!strncmp(allday, "Off", sizeof("Off")))
+       {
+               st.type = CALENDAR_TIME_UTIME;
+               st.time.utime = _convert_to_utime(sdate, stime);
+               ret = calendar_record_set_str(event, _calendar_event.start_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.start_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(event, _calendar_event.start_time, st);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.start_time\n");
+                       return -1;
+               }
+
+               et.type = CALENDAR_TIME_UTIME;
+               et.time.utime = _convert_to_utime(edate, etime);
+               ret = calendar_record_set_str(event, _calendar_event.end_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.end_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(event, _calendar_event.end_time, et);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.end_time\n");
+                       return -1;
+               }
+       } else {
+               _convert_to_datetime(sdate, &y, &m, &d);
+               st.type = CALENDAR_TIME_LOCALTIME;
+               st.time.date.year = y;
+               st.time.date.month = m;
+               st.time.date.mday = d;
+               ret = calendar_record_set_str(event, _calendar_event.start_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.start_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(event, _calendar_event.start_time, st);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.start_time\n");
+                       return -1;
+               }
+
+               _convert_to_datetime(edate, &y, &m, &d);
+               et.type = CALENDAR_TIME_LOCALTIME;
+               et.time.date.year = y;
+               et.time.date.month = m;
+               et.time.date.mday = d;
+               ret = calendar_record_set_str(event, _calendar_event.end_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.end_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(event, _calendar_event.end_time, et);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_event.end_time\n");
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static int __dft_event_set_3(calendar_record_h event, int occurence, int status, int sensitivity)
+{
+       int ret;
+
+       ret = calendar_record_set_int(event, _calendar_event.count, occurence);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_event.count\n");
+               return -1;
+       }
+       ret = calendar_record_set_int(event, _calendar_event.busy_status, status);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_event.busy_status\n");
+               return -1;
+       }
+       ret = calendar_record_set_int(event, _calendar_event.sensitivity, sensitivity);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_event.sensitivity\n");
+               return -1;
+       }
+       return 0;
+}
+
+static int  __dft_todo_set_1(calendar_record_h todo, int book_id, char *subject, char *location)
+{
+       int ret;
+
+       ret = calendar_record_set_int(todo, _calendar_todo.calendar_book_id, book_id);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_todo.calendar_book_id\n");
+               return -1;
+       }
+       ret = calendar_record_set_str(todo, _calendar_todo.summary, subject);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_todo.summary\n");
+               return -1;
+       }
+       ret = calendar_record_set_str(todo, _calendar_todo.location, location);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_todo.location\n");
+               return -1;
+       }
+       return 0;
+}
+
+static int __dft_todo_set_2(calendar_record_h todo, char *allday, char *sdate, char *stime, char *edate, char *etime)
+{
+       int ret;
+       int y, m, d;
+       calendar_time_s st = {0}, et = {0};
+
+       if (!strncmp(allday, "Off", sizeof("Off")))
+       {
+               st.type = CALENDAR_TIME_UTIME;
+               st.time.utime = _convert_to_utime(sdate, stime);
+               ret = calendar_record_set_str(todo, _calendar_todo.start_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.start_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(todo, _calendar_todo.start_time, st);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.start_time\n");
+                       return -1;
+               }
+
+               et.type = CALENDAR_TIME_UTIME;
+               et.time.utime = _convert_to_utime(edate, etime);
+               ret = calendar_record_set_str(todo, _calendar_todo.due_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.due_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(todo, _calendar_todo.due_time, et);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.due_time\n");
+                       return -1;
+               }
+       } else {
+               _convert_to_datetime(sdate, &y, &m, &d);
+               st.type = CALENDAR_TIME_LOCALTIME;
+               st.time.date.year = y;
+               st.time.date.month = m;
+               st.time.date.mday = d;
+               ret = calendar_record_set_str(todo, _calendar_todo.start_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.start_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(todo, _calendar_todo.start_time, st);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.start_time\n");
+                       return -1;
+               }
+
+               _convert_to_datetime(edate, &y, &m, &d);
+               et.type = CALENDAR_TIME_LOCALTIME;
+               et.time.date.year = y;
+               et.time.date.month = m;
+               et.time.date.mday = d;
+               ret = calendar_record_set_str(todo, _calendar_todo.due_tzid, "Asia/Seoul");
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.due_tzid\n");
+                       return -1;
+               }
+               ret = calendar_record_set_caltime(todo, _calendar_todo.due_time, et);
+               if(CALENDAR_ERROR_NONE != ret)
+               {
+                       printf("failed to set _calendar_todo.due_time\n");
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static int __dft_todo_set_3(calendar_record_h todo, int occurence, int status, int sensitivity)
+{
+       int ret;
+
+       ret = calendar_record_set_int(todo, _calendar_todo.count, occurence);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_todo.count\n");
+               return -1;
+       }
+       ret = calendar_record_set_int(todo, _calendar_todo.todo_status, status);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_todo.todo_status\n");
+               return -1;
+       }
+       ret = calendar_record_set_int(todo, _calendar_todo.sensitivity, sensitivity);
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("failed to set _calendar_todo.sensitivity\n");
+               return -1;
+       }
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       FILE *file;
+       int ret;
+       int cnt;
+       int type;
+       char path[256] = {0};
+       char _cnt[16] = {0};
+
+       char subject[MAX_COLS];
+       char location[MAX_COLS];
+       char sdate[16];
+       char stime[16];
+       char edate[16];
+       char etime[16];
+       char allday[16];
+       int occurence;
+       char reminder[16];
+       int reminder_value;
+       int category;
+       int status;
+       int sensitivity;
+       char description[MAX_COLS];
+       calendar_record_h record = NULL;
+
+       printf("argc(%d)\n", argc);
+
+       if (argc != 3) {
+               printf("Check parameters.\n");
+               __dft_calendar_help();
+               return -1;
+       }
+
+       snprintf(path, sizeof(path), "%s", argv[1]);
+       snprintf(_cnt, sizeof(_cnt), "%s", argv[2]);
+       cnt = atoi(_cnt);
+
+       type = __dft_get_file_type(argv[1]);
+       if (type != CALENDAR_BOOK_TYPE_EVENT && type != CALENDAR_BOOK_TYPE_TODO)
+       {
+               printf("Invalid book type");
+               return -1;
+       }
+
+       if (cnt <= 0) {
+               printf("Invalid count(%d)\n", cnt);
+               return -1;
+       }
+
+       file = fopen(path, "r");
+       if (file == NULL) {
+               printf("Failed to open file(%s)\n", path);
+               return -1;
+       }
+
+       ret = calendar_connect();
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               printf("calendar_connect() failed\n");
+               fclose(file);
+               return -1;
+       }
+
+       while ( !feof(file) && fscanf(file,
+                               "%32767[^\t]\t %32767[^\t]\t "
+                               "%s %s %s %s"
+                               "%s %d "
+                               "%s %d "
+                               "%d %d %d "
+                               "%32767[^\0] ",
+                               subject, location,
+                               sdate, stime, edate, etime,
+                               allday, &occurence,
+                               reminder, &reminder_value,
+                               &category, &status, &sensitivity,
+                               description) > 1) {
+
+               switch (type)
+               {
+               case CALENDAR_BOOK_TYPE_EVENT:
+                       ret = CALENDAR_ERROR_NONE;
+
+                       ret |= calendar_record_create(_calendar_event._uri, &record);
+                       ret |= __dft_event_set_1(record, 1, subject, location);
+                       ret |= __dft_event_set_2(record, allday, sdate, stime, edate, etime);
+                       ret |= __dft_event_set_3(record, occurence, status, sensitivity);
+                       ret |= calendar_db_insert_record(record, NULL);
+                       ret |= calendar_record_destroy(record, true);
+
+                       if(CALENDAR_ERROR_NONE != ret)
+                       {
+                               printf("__dft_work_event() failed\n");
+                               return -1;
+                       }
+                       break;
+
+               case CALENDAR_BOOK_TYPE_TODO:
+                       ret = CALENDAR_ERROR_NONE;
+
+                       ret |= calendar_record_create(_calendar_todo._uri, &record);
+                       ret |= __dft_todo_set_1(record, 1, subject, location);
+                       ret |= __dft_todo_set_2(record, allday, sdate, stime, edate, etime);
+                       ret |= __dft_todo_set_3(record, occurence, status, sensitivity);
+                       ret |= calendar_db_insert_record(record, NULL);
+                       ret |= calendar_record_destroy(record, true);
+
+                       if(CALENDAR_ERROR_NONE != ret)
+                       {
+                               printf("__dft_work_todo() failed\n");
+                               return -1;
+                       }
+                       break;
+               }
+
+               cnt--;
+               if (cnt <= 0) {
+                       break;
+               }
+       }
+
+       fclose(file);
+       ret = calendar_disconnect();
+       if(CALENDAR_ERROR_NONE != ret)
+       {
+               printf("calendar_disconnect() failed \n");
+               return -1;
+       }
+       return 0;
+}
diff --git a/dft/src/dft_util.c b/dft/src/dft_util.c
new file mode 100644 (file)
index 0000000..2f4794e
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <string.h>
+#include <glib.h>
+#include <unicode/ucal.h>
+#include <unicode/ustring.h>
+#include <unicode/ustdio.h>
+#include <unicode/udat.h>
+#include <sys/types.h>
+
+#define ms2sec(ms) (long long int)(ms / 1000.0)
+#define sec2ms(s) (s * 1000.0)
+
+long long int _convert_to_utime(char *date, char *time)
+{
+       int y, mon, d, h, min;
+       char buf[8];
+       UErrorCode status = U_ZERO_ERROR;
+       UCalendar *cal;
+       UDate ud;
+
+       if (date == NULL) {
+               printf("Invalid argument: data is NULL\n");
+               return -1;
+       }
+
+       if (time == NULL) {
+               printf("Invalid argument: time is NULL\n");
+               return -1;
+       }
+
+       cal = ucal_open(NULL, -1, NULL, UCAL_TRADITIONAL, &status);
+       if (U_FAILURE(status)) {
+               printf("ucal_open failed (%s)", u_errorName(status));
+               return -1;
+       }
+
+       snprintf(buf, 5, "%s", date + 4);
+       y = atoi(buf);
+       snprintf(buf, 3, "%s", date + 2);
+       mon = atoi(buf);
+       snprintf(buf, 3, "%s", date);
+       d = atoi(buf);
+
+       snprintf(buf, 3, "%s", time);
+       h = atoi(buf);
+       snprintf(buf, 3, "%s", time + 2);
+       min = atoi(buf);
+
+       ucal_setDateTime(cal, y, mon, d, h, min, 0, &status);
+       if (U_FAILURE(status)) {
+               printf("ucal_setDate failed (%s)", u_errorName(status));
+               return -1;
+       }
+
+       ud = ucal_getMillis(cal, &status);
+       if (U_FAILURE(status)) {
+               printf("ucal_getMillis failed (%s)", u_errorName(status));
+               return -1;
+       }
+       ucal_close(cal);
+       return ms2sec(ud);
+}
+
+int _convert_to_datetime(char *date, int *y, int *m, int *d)
+{
+       char buf[8];
+
+       if (date == NULL) {
+               printf("Invalid argument: data is NULL\n");
+               return -1;
+       }
+
+       snprintf(buf, 5, "%s", date + 4);
+       *y = atoi(buf);
+       snprintf(buf, 3, "%s", date + 2);
+       *m = atoi(buf);
+       snprintf(buf, 3, "%s", date);
+       *d = atoi(buf);
+       return 0;
+}
diff --git a/dft/src/dft_util.h b/dft/src/dft_util.h
new file mode 100644 (file)
index 0000000..3cd74f2
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+long long int _convert_to_utime(char *date, char *time);
+int _convert_to_datetime(char *date, int *y, int *m, int *d);
diff --git a/include/calendar2.h b/include/calendar2.h
new file mode 100755 (executable)
index 0000000..91f5b6f
--- /dev/null
@@ -0,0 +1,1107 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_CALENDAR_H__
+#define __TIZEN_SOCIAL_CALENDAR_H__
+
+#include <calendar_errors.h>
+#include <calendar_view.h>
+#include <calendar_db.h>
+#include <calendar_filter.h>
+#include <calendar_list.h>
+#include <calendar_query.h>
+#include <calendar_record.h>
+#include <calendar_service.h>
+#include <calendar_vcalendar.h>
+#include <calendar_reminder.h>
+
+#endif /* __TIZEN_SOCIAL_CALENDAR_H__ */
+
+/**
+ * @ingroup CAPI_SOCIAL_FRAMEWORK
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_MODULE Calendar(New)
+ *
+ * @brief The Calendar Service API provides functions for managing calendars(including events, to-dos).
+ * This API allows you not only to store information about calendar but also to query calendar information.
+ *
+ * @section CAPI_SOCIAL_CALENDARS_SVC_MODULE_HEADER Required Header
+ *  \#include <calendar2.h>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_OVERVIEW Overview
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_Records Records
+ * An important concept in Calendar 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 structure
+ * describing a single (but complex) entity, like a calendar event or a time zone. A record has
+ * many properties, for example, a to-do record has the to-do's description, priority, progress,
+ * created, last modified and completed time, plus many others.
+ *
+ * A record can also contain an identifier field, which holds an identifier of another record.
+ * Setting this field's value establishes a relation between the records, for example,
+ * a calendar event contains the identifier of a calendar book to which it belongs.
+ *
+ * Records contain properties of basic types: integer, lli (long integer, long long int), double,
+ * string, bool and time. The time type holds either a long long int, or three integers
+ * (year, month, day). There are setter and getter functions for each type:
+ *
+ * <table>
+ * <tr>
+ *     <th> Property </th>
+ *     <th> Setter </th>
+ *     <th> Getter </th>
+ * </tr>
+ * <tr>
+ *     <td> integer </td>
+ *     <td> calendar_record_set_int </td>
+ *     <td> calendar_record_get_int </td>
+ * </tr>
+ * <tr>
+ *     <td> long integer </td>
+ *     <td> calendar_record_set_lli </td>
+ *     <td> calendar_record_get_lli </td>
+ * </tr>
+ * <tr>
+ *     <td> double </td>
+ *     <td> calendar_record_set_double </td>
+ *     <td> calendar_record_get_double </td>
+ * </tr>
+ * <tr>
+ *     <td> string </td>
+ *     <td> calendar_record_set_str </td>
+ *     <td> calendar_record_get_str </td>
+ * </tr>
+ * <tr>
+ *     <td> bool </td>
+ *     <td> calendar_record_set_bool </td>
+ *     <td> calendar_record_get_bool </td>
+ * </tr>
+ * <tr>
+ *     <td> time </td>
+ *     <td> calendar_record_set_time </td>
+ *     <td> calendar_record_get_time </td>
+ * </tr>
+ * </table>
+ *
+ * A record's type is identified by a structure called the view. For example,
+ * the _calendar_event view describes the properties of the calendar event record.
+ * Every view has a special field - _uri - that uniquely identifies the view.
+ * In many cases you wil need to provide the _uri value to indicate what
+ * type of record you wish to create or operate on.
+ *
+ * To use a record, you must obtain its handle. There are many ways to obtains it,
+ * including creating a new record and referring to child records of a record.
+ *
+ * Example: the code below creates an event and inserts it into default event book
+ * (see below on calendar books).
+ *
+ * @code
+ * // create an event
+ * calendar_record_h event;
+ * calendar_record_create(_calendar_event._uri, &event);
+ *
+ * // set event summary
+ * calendar_record_set_str(event, _calendar_event.summary, "Meeting");
+ *
+ * // put the event into the default calendar book for events
+ * calendar_record_set_int(event, _calendar_event.calendar_book_id, book_id);
+ *
+ * // insert calendar book into the database
+ * calendar_db_insert_record(event);
+ * @endcode
+ *
+ * Records of certain type also hold 'child list' properties. If a record has
+ * property of this type, it can be a parent of other records, called child records.
+ * For example, attendee records can hold an event's identifier in their event_id
+ * property. The event is the parent record of the child attendee records.
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_Calendar_books Calendar books
+ * A calendar book is a placeholder for other records in Calendar API.
+ * Every event and to-do has to belong to a calendar book.
+ * There are two built-in calendar books: one for events, and one for to-dos,
+ * identified by DEFAULT_EVENT_CALENDAR_BOOK_ID and DEFAULT_TODO_CALENDAR_BOOK_ID,
+ * respectively.
+ *
+ * To receive a list of existing calendar books, use the following:
+ *
+ * @code
+ * calendar_list_h calendar_book_list = NULL;
+ * calendar_db_get_all_records(_calendar_calendar_book._uri, 0, 0, &calendar_book_list);
+ * @endcode
+ *
+ * The parameters of calendar_db_get_all_records() are:
+ * - type of records you wish to receive - _uri field of the view representing desired type,
+ * - index from which results should be received (0 for all records),
+ * - maximum number of results (0 means no limit),
+ * - a list structure to hold the results.
+ *
+ * The list should be destroyed later with calendar_list_destroy().
+ *
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_Events_and_instances Events and instances
+ * Two important concepts are event and instance. An event record describes
+ * various properties of the event, like description, categories, priority
+ * and many others. It also contains information on when the event takes place,
+ * there can be more than one instance of the event. Each instance has its
+ * corresponding instance record.
+ *
+ * For example, if an event has the following properties:
+ *
+ * - start date on 2012-10-09 (Tuesday),
+ * - frequency set to 'WEEKLY',
+ * - interval set to 1,
+ * - count set to 3,
+ *
+ * it will generate three instances:
+ *
+ * - 2012-10-09
+ * - 2012-10-16
+ * - 2012-10-22
+ *
+ * Interval is a multiplier of frequency, which means that if it is set to N,
+ * instances occur every N weeks (or whatever was set in frequency attribute).
+ *
+ * The recurrence model in Calendar API is compliant with iCalendar specification
+ * (<a href="http://www.ietf.org/rfc/rfc2445.txt">www.ietf.org/rfc/rfc2445.txt</a>).
+ * The following event properties have the same functionality as their corresponding
+ * values in iCalendar:
+ *
+ * @code
+ * freq
+ * count
+ * interval
+ * bysecond
+ * byminute
+ * byhour
+ * byday
+ * bymonthday
+ * byyearday
+ * byweekno
+ * bymonth
+ * bysetpos
+ * wkst
+ * @endcode
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_Calendar_time_structure Calendar time structure
+ * The calendar time structure, calendar_caltime_s, is defined as follows:
+ *
+ * @code
+ * typedef struct
+ * {
+ *     calendar_time_type_e type;
+ *     union {
+ *         long long int utime;
+ *         struct {
+ *             int year;
+ *             int month;
+ *             int mday;
+ *         } date;
+ *     } time;
+ * } calendar_time_s;
+ * @endcode
+ *
+ * The structure should be used when setting the calendar time type
+ * (_CALENDAR_PROPERTY_CALTIME) properties of records.
+ *
+ * It can hold two types of data: UTC time (long long int) and date,
+ * given as year, month and day of the month (three integers). These types
+ * are identified by values of calendar_time_type_e, which are CALENDAR_TIME_UTIME
+ * and CALENDAR_TIME_LOCALTIME, respectively. The data type determines the usage
+ * of the structure.
+ *
+ * <table>
+ * <tr>
+ *     <th> Identifier </th>
+ *     <th> Type </th>
+ *     <th> Name </th>
+ *     <th> Purpose </th>
+ * </tr>
+ * <tr>
+ *     <td> CALENDAR_TIME_UTIME </td>
+ *     <td> long long int </td>
+ *     <td> utime </td>
+ *     <td> UTC time, used to describe non-all-day events </td>
+ * </tr>
+ * <tr>
+ *     <td> CALENDAR_TIME_LOCALTIME </td>
+ *     <td> struct </td>
+ *     <td> date </td>
+ *     <td> date only (year, month and day of the month), used to describe all day events </td>
+ * </tr>
+ * </table>
+ *
+ *
+ * 1. UTC time usage
+ *
+ * Structures with UTC time should be used for non-all-day events.
+ * In such cases, the API user should convert local time to UTC time. The local
+ * time zone identifier should be stored in the record, in the corresponding
+ * property.
+ *
+ * For example, when setting starting time of an event, the local
+ * time zone should be stored in start_tzid.
+ *
+ * When converting local time to UTC time, the function below can be useful.
+ * The function converts the given date and time to the corresponding
+ * UTC time, considering the given time zone (first argument).
+ * The function uses UCalendar, see <a href="http://icu-project.org/apiref/icu4c/ucal_8h.html">
+ * ucal_8h.html</a>
+ *
+ * @code
+ * #define ms2sec(ms) (long long int)(ms / 1000.0)
+ *
+ * long long int _time_convert_itol(char *tzid, int y, int mon, int d, int h, int min, int s)
+ * {
+ *     long long int lli;
+ *     UCalendar *ucal;
+ *     UErrorCode status = U_ZERO_ERROR;
+ *
+ *     UChar *_tzid = NULL;
+ *
+ *     if (tzid == NULL)
+ *     {
+ *         tzid = "Etc/GMT";
+ *     }
+ *     _tzid = (UChar*)calloc(strlen(tzid) + 1, sizeof(UChar));
+ *     if (_tzid == NULL)
+ *     {
+ *         return -1;
+ *     }
+ *     u_uastrcpy(_tzid, tzid);
+ *
+ *     ucal = ucal_open(_tzid, u_strlen(_tzid), "en_US", UCAL_TRADITIONAL, &status);
+ *     if (U_FAILURE(status)) {
+ *         printf("ucal_open failed (%s)\n", u_errorName(status));
+ *         return -1;
+ *     }
+ *
+ *     ucal_set(ucal, UCAL_YEAR, y);
+ *     ucal_set(ucal, UCAL_MONTH, mon -1);
+ *     ucal_set(ucal, UCAL_DATE, d);
+ *     ucal_set(ucal, UCAL_HOUR, h);
+ *     ucal_set(ucal, UCAL_MINUTE, min);
+ *     ucal_set(ucal, UCAL_SECOND, s);
+ *     lli = ms2sec(ucal_getMillis(ucal, &status));
+ *     ucal_close(ucal);
+ *     if (_tzid) free(_tzid);
+ *
+ *     return lli;
+ * }
+ * @endcode
+ *
+ * Sample code:
+ *
+ * @code
+ * // fill calendar time structures (start and end time)
+ * calendar_time_s st = {0};
+ * calendar_time_s et = {0};
+ *
+ * st.type = CALENDAR_TIME_UTIME;
+ * st.time.time = _time_convert_itol("Asia/Seoul", 2012, 9, 15, 11, 0, 0);
+ *
+ * et.type = CALENDAR_TIME_UTIME;
+ * et.time.time = _time_convert_itol("Asia/Seoul", 2012, 9, 15, 12, 0, 0);
+ *
+ * // create an event record
+ * // ...
+ *
+ * // set local time zone of start time
+ * calendar_record_set_str(event, _calendar_event.start_tzid, "Asia/Seoul");
+ *
+ * // set start time
+ * calendar_record_set_time(event, _calendar_event.start_time, st);
+ *
+ * // set local time zone of end time
+ * calendar_record_set_str(event, _calendar_event.end_tzid, "Asia/Seoul");
+ *
+ * // set end time
+ * calendar_record_set_time(event, _calendar_event.start_time, et);
+ * @endcode
+ *
+ *
+ * 2. Date usage
+ *
+ * Another usage of time structure is an all day event. In case of such events,
+ * the structure's type field should be set to CALENDAR_TIME_LOCALTIME.
+ * Only the date (no time) will be stored. Such structures can be used to set start
+ * and end time of an event.
+ *
+ * Both start and end time of the event should be set. Start and end time
+ * do not have to be equal. If they are not, the event's duration will be more
+ * than one day. Note that in such cases there are no instances created,
+ * as this is still a non-recurring event.
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_Creating_a_recurring_event Creating a recurring event
+ * To create a recurring event in Calendar API, first you need to create
+ * and fill start and end time structures.
+ *
+ * @code
+ * calendar_time_s st = {0};
+ * calendar_time_s et = {0};
+ *
+ * st.type = CALENDAR_TIME_UTIME;
+ * st.time.time = _time_convert_itol("Asia/Seoul", 2012, 9, 15, 11, 0, 0);
+ *
+ * et.type = CALENDAR_TIME_UTIME;
+ * et.time.time = _time_convert_itol("Asia/Seoul", 2012, 9, 15, 12, 0, 0);
+ * @endcode
+ *
+ * Then you can create and configure an event record.
+ *
+ * The time structures created before should be set using the corresponding setter function.
+ * Then, the remaining properties should be set - frequency, interval and count.
+ *
+ * The last step is inserting the event into the database. Records representing
+ * instances of the event are created when the event record is inserted.
+ *
+ * @code
+ * calendar_record_h event;
+ * calendar_record_create(_calendar_event._uri, &event);
+ *
+ * calendar_record_set_str(event, _calendar_event.start_tzid, "Asia/Seoul");
+ * calendar_record_set_time(event, _calendar_event.start_time, st);
+ * calendar_record_set_str(event, _calendar_event.end_tzid, "Asia/Seoul");
+ * calendar_record_set_time(event, _calendar_event.start_time, et);
+ *
+ * calendar_record_set_int(event, _calendar_event.freq, CALENDAR_RECURRENCE_WEEKLY);
+ * calendar_record_set_int(event, _calendar_event.interval, 1)
+ * calendar_record_set_int(event, _calendar_event.count, 3);
+ *
+ * calendar_db_insert_record(event);
+ * @endcode
+ *
+ *
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_Filters_and_queries Filters and queries
+ * Queries are used to retrieve data which satisfies given criteria, like an integer
+ * property being greater than a given value, or a string property containing a given substring.
+ * The criteria are defined by creating filters and adding conditions to them, joining them
+ * with logical operators. Also, instead of a condition, another filter can be added,
+ * which can be used to create more complex filters.
+ *
+ * Operator precedence in filters determined by the order in which the
+ * conditions and filters are added.
+ *
+ * When a filter is ready, it can be set as a property of a query.
+ * Other query properties allow configuring how the returned results
+ * are grouped and sorted.
+ *
+ * Operator precedence in filters is determined by the order in which the
+ * conditions and filters are added are added.
+ * For example, if the following sequence is added:
+ *
+ * @code
+ * Condition C1
+ * OR
+ * Condition C2
+ * AND
+ * Condition C3
+ * @endcode
+ *
+ * the result is:
+ *
+ * @code
+ * (C1 OR C2) AND C3
+ * @endcode
+ *
+ * Another example, the sequence:
+ *
+ * @code
+ * Filter F1:
+ * Condition C1
+ * OR
+ * Condition C2
+ *
+ * Filter F2:
+ * Condition C3
+ * OR
+ * Condition C4
+ *
+ * Filter F3:
+ * Condition C5
+ * AND
+ * F1
+ * AND
+ * F2
+ * @endcode
+ *
+ * results in:
+ *
+ * @code
+ * Filter F3:
+ * (C5 AND F1) AND F2
+ * @endcode
+ *
+ * which is:
+ *
+ * @code
+ * Filter F3:
+ * (C5 AND (C1 OR C2)) AND (C3 OR C4)
+ * @endcode
+ *
+ * The following code creates a filter, accepting events with high priority
+ * or those that include the word "meeting" in their description.
+ *
+ * @code
+ * calendar_filter_h filter = NULL;
+ *
+ * // create a filter returning event type records
+ * calendar_filter_create(_calendar_event._uri, &filter);
+ *
+ * // add 'priority equals high' condition
+ * calendar_filter_add_int(filter, _calendar_event.priority, CALENDAR_MATCH_EQUAL,
+ *         CALENDAR_EVENT_PRIORITY_HIGH);
+ *
+ * // add OR operator
+ * calendar_filter_add_operator(filter, CALENDAR_FILTER_OPERATOR_OR);
+ *
+ * // add 'description contains "meeting"' condition
+ * calendar_filter_add_str(filter, _calendar_event.description, CALENDAR_MATCH_CONTAINS,
+ *         "meeting");
+ * @endcode
+ *
+ * The filter should be inserted into a query and the query should be executed:
+ *
+ * @code
+ * calendar_query_h query = NULL;
+ * calendar_list_h list = NULL;
+ *
+ * // create a query returning event type records
+ * calendar_query_create(_calendar_event._uri, &query);
+ *
+ * // add the filter
+ * calendar_query_set_filter(query, filter);
+ *
+ * // execute the query, results are returned in a list
+ * calendar_db_get_records_with_query(query, 0, 0, &list);
+ *
+ * calendar_filter_destroy(&filter);
+ * calendar_query_destroy(&query);
+ *
+ * // use the list
+ * // ...
+ *
+ * calendar_list_destroy(&list);
+ * @endcode
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_MODULE_View_properties View properties
+ * In \ref CAPI_SOCIAL_CALENDAR_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. attendee and alarm
+ * views hold id of their corresponding events or to-dos in event_id or todo_id property repectively
+ * (as children of the corresponding events or to-dos record).
+ *
+ * Properties of type 'record' are other records. For example, a event record has 'attendee'
+ * and 'alarm', which means that records of those types can be children
+ * of event type records.
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CALENDAR_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_DATABASE_MODULE Database
+ *
+ * @brief The calendar database API provides the set of the definitions and interfaces that enable you to handle calendar database.
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_DATABASE_MODULE_HEADER Required Header
+ *  \#include <calendar2.h>
+ *
+ * <BR>
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CALENDAR_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_RECORD_MODULE Record
+ *
+ * @brief The calendar record API provides the set of the definitions and interfaces that enable you to get/set data from/to calendar record handle.
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_RECORD_MODULE_HEADER Required Header
+ *  \#include <calendar2.h>
+ *
+ * <BR>
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CALENDAR_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_LIST_MODULE List
+ *
+ * @brief This page provides information about list.
+ *
+ * @brief The calendar database API provides the set of the definitions and interfaces that enable you to handle list.
+ *  \#include <calendar2.h>
+ *
+ * <BR>
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CALENDAR_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_FILTER_MODULE Filter
+ *
+ * @brief The calendar database API provides the set of the definitions and interfaces that enable you to handle filter.
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_FILTER_MODULE_HEADER Required Header
+ *  \#include <calendar2.h>
+ *
+ * <BR>
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CALENDAR_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_QUERY_MODULE Query
+ *
+ * @brief The calendar database API provides the set of the definitions and interfaces that enable you to handle query.
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_QUERY_MODULE_HEADER Required Header
+ *  \#include <calendar2.h>
+ *
+ * <BR>
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CALENDAR_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_VCALENDAR_MODULE vCalendar
+ *
+ * @brief The calendar record API provides the set of the definitions and interfaces that enable you to get/set data from/to vCalendar.
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VCALENDAR_MODULE_HEADER Required Header
+ *  \#include <calendar2.h>
+ *
+ * <BR>
+ */
+
+/**
+ * @ingroup CAPI_SOCIAL_CALENDAR_SVC_MODULE
+ * @defgroup CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE View/Property
+ *
+ * @brief This page provides information about views with properties.
+ *
+ * @section CAPI_SOCIAL_CALENDAR_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. 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> calendar_record_set_str </td>
+ *    <td> calendar_record_get_str </td>
+ * </tr>
+ * <tr>
+ *    <td> integer </td>
+ *    <td> calendar_record_set_int </td>
+ *    <td> calendar_record_get_int </td>
+ * </tr>
+ * <tr>
+ *    <td> boolean </td>
+ *    <td> calendar_record_set_bool </td>
+ *    <td> calendar_record_get_bool </td>
+ * </tr>
+ * <tr>
+ *    <td> long integer </td>
+ *    <td> calendar_record_set_lli </td>
+ *    <td> calendar_record_get_lli </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 \ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_event
+ * has a 'calendar_alarm' property of type 'record'. This means that records of type calendar_alarm (\ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_alarm)
+ * can be children of the event record. If a name record holds the identifier
+ * of a event record in its 'event_id' property, it is the child record of the corresponding
+ * event record.
+ *
+ * Records can have many children of a given type.
+ *
+ * Please refer to the main section of Calendar API for a more detailed explanation and examples.
+ *
+ * @section CAPI_SOCIAL_CCALENDAR_SVC_VIEW_MODULE_HEADER Required Header
+ *  \#include <calendar2.h>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_book _calendar_book view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> id </td><td> read only </td></tr>
+ *     <tr><td> string </td><td> uid </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> name </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> color </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> visibility </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sync_event </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> is_deleted </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> account_id </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> store_type </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data1 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data2 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data3 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data4 </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_event _calendar_event view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write once </td></tr>
+ *     <tr><td> string </td><td> summary </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> categories </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> exdate </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> event_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> priority </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> timezone </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> person_id </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> busy_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sensitivity </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> uid </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> organizer_name </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> organizer_email </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> meeting_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> original_event_id </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> latitude </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> longitude </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> email_id </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> created_time </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> last_modified_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> is_deleted </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> freq </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> range_type </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> until_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> count </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> interval </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysecond </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byminute </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byhour </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonthday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byyearday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byweekno </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonth </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysetpos </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> wkst </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> recurrence_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> rdate </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_attendee </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> has_alarm </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_system_type </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data1 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data2 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data3 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data4 </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> start_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> start_tzid </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> end_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> end_tzid </td><td> read, write </td></tr>
+ *     <tr><td> child list </td><td> calendar_alarm </td><td> read, write </td></tr>
+ *     <tr><td> child list </td><td> calendar_attendee </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_todo _calendar_todo view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write once </td></tr>
+ *     <tr><td> string </td><td> summary </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> categories </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> todo_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> priority </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sensitivity </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> uid </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> latitude </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> longitude </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> created_time </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> last_modified_time </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> completed_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> progress </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> is_deleted </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> freq </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> range_type </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> until_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> count </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> interval </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysecond </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byminute </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byhour </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonthday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byyearday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byweekno </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonth </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysetpos </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> wkst </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_alarm </td><td> read only </td></tr>
+ *     <tr><td> string </td><td> sync_data1 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data2 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data3 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data4 </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> start_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> start_tzid </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> due_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> due_tzid </td><td> read, write </td></tr>
+ *     <tr><td> child list </td><td> calendar_alarm </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_timezone _calendar_timezone view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> tz_offset_from_gmt </td><td> read only </td></tr>
+ *     <tr><td> string </td><td> standard_name </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> standard_start_month </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> standard_start_position_of_week </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> standard_start_day </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> standard_start_hour </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> standard_bias </td><td> read only </td></tr>
+ *     <tr><td> string </td><td> day_light_name </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> day_light_start_month </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> day_light_start_position_of_week </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> day_light_start_day </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> day_light_start_hour </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> day_light_bias </td><td> read only </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_attendee _calendar_attendee view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> event_id </td><td> read only </td></tr>
+ *     <tr><td> string </td><td> number </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> type </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> person_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> uid </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> group </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> email </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> role </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> rsvp </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> delegate_uri </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> delegator_uri </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> name </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_alarm _calendar_alarm view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> event_id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> todo_id </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> type </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> tick </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> tick_unit </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> tone </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> alarm_id </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_updated_info _calendar_updated_info view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> modified_status </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_event_calendar_book _calendar_event_calendar_book view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> event_id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> summary </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> categories </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> exdate </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> event_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> priority </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> timezone </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> person_id </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> busy_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sensitivity </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> uid </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> organizer_name </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> organizer_email </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> meeting_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> original_event_id </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> latitude </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> longitude </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> email_id </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> created_time </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> last_modified_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> is_deleted </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> freq </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> range_type </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> until_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> count </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> interval </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysecond </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byminute </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byhour </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonthday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byyearday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byweekno </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonth </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysetpos </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> wkst </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> recurrence_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> rdate </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_attendee </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_alarm </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> calendar_system_type </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data1 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data2 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data3 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data4 </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> start_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> start_tzid </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> end_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> end_tzid </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_visibility </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_account_id </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_todo_calendar_book _calendar_todo_calendar_book view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> todo_id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> summary </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> categories </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> todo_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> priority </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sensitivity </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> uid </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> latitude </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> longitude </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> created_time </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> last_modified_time </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> completed_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> progress </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> is_deleted </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> freq </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> range_type </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> until_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> count </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> interval </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysecond </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byminute </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byhour </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonthday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byyearday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byweekno </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonth </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysetpos </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> wkst </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_alarm </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data1 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data2 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data3 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data4 </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> start_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> start_tzid </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> due_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> due_tzid </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_visibility </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_account_id </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_event_calendar_book_attendee _calendar_event_calendar_book_attendee view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> event_id </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> summary </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> categories </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> exdate </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> event_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> priority </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> timezone </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> person_id </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> busy_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sensitivity </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> uid </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> organizer_name </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> organizer_email </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> meeting_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> original_event_id </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> latitude </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> longitude </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> email_id </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> created_time </td><td> read, write </td></tr>
+ *     <tr><td> long long int </td><td> last_modified_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> is_deleted </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> freq </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> range_type </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> until_time </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> count </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> interval </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysecond </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byminute </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byhour </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonthday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byyearday </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> byweekno </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bymonth </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> bysetpos </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> wkst </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> recurrence_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> rdate </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_attendee </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_alarm </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> calendar_system_type </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data1 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data2 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data3 </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> sync_data4 </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> start_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> start_tzid </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> end_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> end_tzid </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_visibility </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_account_id </td><td> read, write </td></tr>
+ *     <tr><td> filter string </td><td> attendee_email </td><td> read, write </td></tr>
+ *     <tr><td> filter string </td><td> attendee_name </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_instance_normal_calendar_book _calendar_instance_normal_calendar_book view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> event_id </td><td> read only </td></tr>
+ *     <tr><td> calendar time </td><td> start_time </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> end_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> summary </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> busy_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> event_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> priority </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sensitivity </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_rrule </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> latitude </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> longitude </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_alarm </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> original_event_id </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_visibility </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_account_id </td><td> read, write </td></tr>
+ * </table>
+ *
+ * @section CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_instance_allday_calendar_book _calendar_instance_allday_calendar_book view
+ * <table>
+ *     <tr>
+ *     <th> Type </th>
+ *     <th> Property ID </th>
+ *     <th> Read, Write </th>
+ *     </tr>
+ *     <tr><td> string </td><td> _uri </td><td> read only </td></tr>
+ *     <tr><td> integer </td><td> event_id </td><td> read only </td></tr>
+ *     <tr><td> calendar time </td><td> start_time </td><td> read, write </td></tr>
+ *     <tr><td> calendar time </td><td> end_time </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> summary </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> location </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> calendar_book_id </td><td> read, write </td></tr>
+ *     <tr><td> string </td><td> description </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> busy_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> event_status </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> priority </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> sensitivity </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_rrule </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> latitude </td><td> read, write </td></tr>
+ *     <tr><td> double </td><td> longitude </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> has_alarm </td><td> read, write </td></tr>
+ *     <tr><td> integer </td><td> original_event_id </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_visibility </td><td> read, write </td></tr>
+ *     <tr><td> filter integer </td><td> calendar_book_account_id </td><td> read, write </td></tr>
+ * </table>
+ *
+ */
+
+
diff --git a/include/calendar_db.h b/include/calendar_db.h
new file mode 100644 (file)
index 0000000..f784611
--- /dev/null
@@ -0,0 +1,595 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_DB_H__
+#define __TIZEN_SOCAIL_CALENDAR_DB_H__
+
+#include <calendar_types2.h>
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_DATABASE_MODULE
+ * @{
+ */
+
+/**
+ * @brief   Inserts a record to the calendar database.
+ *
+ * @param[in]   record                 The record handle
+ * @param[out]  record_id              The record ID
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_update_record()
+ * @see calendar_db_delete_record()
+ * @see calendar_db_get_record()
+ */
+API int calendar_db_insert_record( calendar_record_h record, int* record_id );
+
+/**
+ * @brief   Gets a record from the calendar database.
+ *
+ * @details This function creates a new record handle from the calendar database by the given @a record_id. \n
+ * @a record will be created, which is filled with record information.
+ *
+ * @remarks  @a record must be released with calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_record_destroy()
+ */
+API int        calendar_db_get_record( const char* view_uri, int record_id, calendar_record_h* record );
+
+/**
+ * @brief Updates a record to the calendar database.
+ *
+ * @param[in]   record          The record handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_insert_record()
+ * @see calendar_db_delete_record()
+ * @see calendar_db_get_record()
+ */
+API int calendar_db_update_record( calendar_record_h record );
+
+/**
+ * @brief Deletes a record from the calendar 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_insert_record()
+ */
+API int calendar_db_delete_record( const char* view_uri, int record_id );
+
+/**
+ * @brief       Retrieves all record as list
+ *
+ * @remarks     @a record_list must be released with calendar_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  #CALENDAR_ERROR_NONE                               Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY              Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre    This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_list_destroy()
+ */
+API int calendar_db_get_all_records( const char* view_uri, int offset, int limit, calendar_list_h* record_list );
+
+/**
+ * @brief       Retrieves records with query handle
+ *
+ * @remarks     @a record_list must be released with calendar_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  #CALENDAR_ERROR_NONE                               Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY              Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre    This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_list_destroy()
+ */
+API int calendar_db_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* record_list );
+
+/**
+ * @brief       Cleans data after sync
+ *
+ * @param[in]   calendar_book_id                       The calendar book ID
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                               Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY              Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre    This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ */
+API int calendar_db_clean_after_sync( int calendar_book_id ); // calendar_svc_clean_after_sync  for EAS sync
+
+/**
+ * @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  #CALENDAR_ERROR_NONE                               Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre    This function requires an open connection to calendar service by calendar_connect2().
+ *
+ * @see calendar_connect()
+ */
+API int calendar_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  #CALENDAR_ERROR_NONE                               Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB                                 Database operation failure
+ *
+ * @pre    This function requires an open connection to calendar service by calendar_connect2().
+ *
+ * @see calendar_connect2()
+ */
+API int calendar_db_get_count_with_query( calendar_query_h query, int *count );
+
+/**
+ * @brief   Inserts multiple records as batch operation to the calendar database.
+ *
+ * @param[in]   record_list                    The record list handle
+ * @param[out]  record_id_array            The record IDs
+ * @param[out]  count                      The number of record ID array
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_update_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_insert_records_async()
+ */
+API int calendar_db_insert_records( calendar_list_h record_list, int** record_id_array, int* count);
+
+/**
+ * @brief   Inserts multiple records as batch operation to the calendar 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_update_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_insert_result_cb
+ */
+API int calendar_db_insert_records_async( calendar_list_h record_list, calendar_db_insert_result_cb callback, void *user_data);
+
+/**
+ * @brief   Updates multiple records as batch operation to the calendar database.
+ *
+ * @param[in]   record_list                    The record list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_insert_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_update_records_async()
+ */
+API int calendar_db_update_records( calendar_list_h record_list);
+
+/**
+ * @brief   Updates multiple records as batch operation to the calendar 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_insert_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_result_cb
+ */
+API int calendar_db_update_records_async( calendar_list_h record_list, calendar_db_result_cb callback, void *user_data);
+
+/**
+ * @brief   Deletes multiple records as batch operation to the calendar 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_insert_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_delete_records_async()
+ */
+API int calendar_db_delete_records(const char* view_uri, int record_id_array[], int count);
+
+/**
+ * @brief   Deletes multiple records as batch operation to the calendar 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_insert_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_result_cb()
+ */
+API int calendar_db_delete_records_async(const char* view_uri, int record_id_array[], int count, calendar_db_result_cb callback, void *user_data);
+
+/**
+ * @brief      Gets the current calendar database version.
+ *
+ * @param[out]  calendar_db_version    The calendar database version
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                               Successful
+ * @retval     #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre     This function requires an open connection to the calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_get_changes_by_version()
+ */
+API int calendar_db_get_current_version(int* calendar_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     #CALENDAR_ERROR_NONE                Successful
+ * @retval     #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @pre                This function requires an open connection to the calendar service by calendar_connect().
+ * @post       calendar_db_changed_cb() will be invoked when the designated view changes.
+ *
+ * @see calendar_connect()
+ * @see calendar_db_changed_cb()
+ * @see calendar_db_remove_changed_cb()
+ */
+API int calendar_db_add_changed_cb(const char* view_uri, calendar_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     #CALENDAR_ERROR_NONE                Successful
+ * @retval     #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @pre                This function requires an open connection to the calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_changed_cb()
+ * @see calendar_db_add_changed_cb()
+ */
+API int calendar_db_remove_changed_cb( const char* view_uri, calendar_db_changed_cb callback, void* user_data );
+
+/**
+ * @brief       Retrieves records with the calendar database version.
+ *
+ * @details            This function will find all changed records since the given @a calendar_db_version
+ *
+ * @remarks     @a change_record_list must be released with calendar_list_destroy() by you.
+ *
+ * @param[in]   view_uri                                       The view URI to get records
+ * @param[in]   calendar_book_id                               The calendar book ID to filter
+ * @param[in]   calendar_db_version                    The calendar database version
+ * @param[out]  record_list                                    The record list
+ * @param[out]  current_calendar_db_version    The current calendar database version
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                               Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY              Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED                  Database operation failure
+ *
+ * @pre    This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_list_destroy()
+ */
+API int calendar_db_get_changes_by_version(const char* view_uri, int calendar_book_id, int calendar_db_version, calendar_list_h* record_list, int *current_calendar_db_version );
+
+/**
+ * @brief   Inserts vcalendar stream to the calendar database.
+ *
+ * @param[in]   vcalendar_stream                The vcalendar stream
+ * @param[out]  record_id_array                 The record IDs to delete
+ * @param[out]  count                           The number of record ID array
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_replace_vcalendars()
+ */
+API int calendar_db_insert_vcalendars(const char* vcalendar_stream, int **record_id_array, int *count);
+
+/**
+ * @brief   Inserts vcalendar stream to the calendar database.
+ *
+ * @param[in]   vcalendar_stream                The vcalendar stream
+ * @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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_replace_vcalendars()
+ * @see calendar_db_insert_result_cb
+ */
+API int calendar_db_insert_vcalendars_async(const char* vcalendar_stream, calendar_db_insert_result_cb callback, void *user_data);
+
+/**
+ * @brief   Replaces vcalendar stream to the calendar database.
+ *
+ * @param[in]   vcalendar_stream                The vcalendar stream
+ * @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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_replace_vcalendars()
+ */
+API int calendar_db_replace_vcalendars(const char* vcalendar_stream, int *record_id_array, int count);
+
+/**
+ * @brief   Replaces vcalendar stream to the calendar database.
+ *
+ * @param[in]   vcalendar_stream                The vcalendar stream
+ * @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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_replace_vcalendars()
+ */
+API int calendar_db_replace_vcalendars_async(const char* vcalendar_stream, int *record_id_array, int count, calendar_db_result_cb callback, void *user_data);
+
+/**
+ * @brief   Replaces a record to the calendar database.
+ *
+ * @param[in]   record                 The record handle
+ * @param[in]   record_id              The record ID
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_update_record()
+ * @see calendar_db_delete_record()
+ * @see calendar_db_get_record()
+ */
+API int calendar_db_replace_record(calendar_record_h record, int record_id);
+
+/**
+ * @brief   Replaces multiple records as batch operation to the calendar database.
+ *
+ * @param[in]   record_list         The record list handle
+ * @param[in]   record_id_array     The record IDs
+ * @param[in]   count               The number of record ID array
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_update_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_replace_record()
+ * @see calendar_db_replace_records_async()
+ */
+API int calendar_db_replace_records(calendar_list_h record_list, int *record_id_array, int count);
+
+/**
+ * @brief   Replaces multiple records as batch operation to the calendar database.
+ *
+ * @param[in]   record_list         The record list handle
+ * @param[in]   record_id_array     The record IDs
+ * @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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_update_records()
+ * @see calendar_db_delete_records()
+ * @see calendar_db_replace_record()
+ * @see calendar_db_result_cb
+ */
+API int calendar_db_replace_records_async(calendar_list_h record_list, int *record_id_array, int count, calendar_db_result_cb callback, void *user_data);
+
+/**
+ * @brief   Gets the last change calendar database version on current connection.
+ *
+ * @param[out]  last_change_version    The calendar database version on current connection
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_DB_FAILED           Database operation failure
+ *
+ * @pre     This function requires an open connection to the calendar service by calendar_connect().
+ *
+ * @see calendar_connect()
+ * @see calendar_db_get_current_version()
+ */
+API int calendar_db_get_last_change_version(int* last_change_version);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_DB_H__ */
+
diff --git a/include/calendar_errors.h b/include/calendar_errors.h
new file mode 100644 (file)
index 0000000..11f91bf
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_ERROR_H__
+#define __TIZEN_SOCAIL_CALENDAR_ERROR_H__
+
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_LIST_MODULE
+ * @{
+ */
+
+typedef enum
+{
+    CALENDAR_ERROR_NONE                 = TIZEN_ERROR_NONE,                     /**< Successful */
+    CALENDAR_ERROR_DB_FAILED            = TIZEN_ERROR_SOCIAL_CLASS | 0x02,      /**< No access to database */
+    CALENDAR_ERROR_DB_RECORD_NOT_FOUND  = TIZEN_ERROR_SOCIAL_CLASS | 0x05,      /**< Not found database */
+    CALENDAR_ERROR_OUT_OF_MEMORY        = TIZEN_ERROR_OUT_OF_MEMORY,            /**< Out of memory */
+    CALENDAR_ERROR_INVALID_PARAMETER    = TIZEN_ERROR_INVALID_PARAMETER,        /**< Invalid parameter */
+    CALENDAR_ERROR_NO_DATA              = TIZEN_ERROR_SOCIAL_CLASS | 0x03,      /**< Requested data does not exist */
+    CALENDAR_ERROR_ITERATOR_END         = TIZEN_ERROR_SOCIAL_CLASS | 0x04,      /**< Iterator is on last position */
+    CALENDAR_ERROR_NOW_IN_PROGRESS      = TIZEN_ERROR_NOW_IN_PROGRESS,          /**< Operation now in progress */
+    CALENDAR_ERROR_ALREADY_IN_PROGRESS  = TIZEN_ERROR_ALREADY_IN_PROGRESS,      /**< Operation already in progress */
+    CALENDAR_ERROR_NOT_PERMITTED        = TIZEN_ERROR_NOT_PERMITTED,            /**< Operation not permitted */
+    CALENDAR_ERROR_IPC                  = TIZEN_ERROR_SOCIAL_CLASS | 0xBF,      /**< Unknown IPC error */
+       CALENDAR_ERROR_FILE_NO_SPACE        = TIZEN_ERROR_FILE_NO_SPACE_ON_DEVICE,  /**< FS Full */
+} calendar_error_e;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_ERROR_H__ */
+
diff --git a/include/calendar_filter.h b/include/calendar_filter.h
new file mode 100644 (file)
index 0000000..b526aa3
--- /dev/null
@@ -0,0 +1,187 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_FILTER_H__
+#define __TIZEN_SOCAIL_CALENDAR_FILTER_H__
+
+#include <calendar_types2.h>
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_FILTER_MODULE
+ * @{
+ */
+
+/**
+ * @brief   Creates a handle to filter.
+ *
+ * @remarks            @a filter must be released with calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY       Out of memory
+ *
+ * @see calendar_filter_destroy()
+ */
+API int calendar_filter_create( const char* view_uri, calendar_filter_h* filter );
+
+/**
+ * @brief   Destroys a filter handle.
+ *
+ * @param[in]   filter    The filter handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_create()
+ */
+API int        calendar_filter_destroy( calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_add_operator()
+ */
+API int        calendar_filter_add_str( calendar_filter_h filter, unsigned int property_id, calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_add_operator()
+ */
+API int        calendar_filter_add_int( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_add_operator()
+ */
+API int        calendar_filter_add_double( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, double 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_add_operator()
+ */
+API int        calendar_filter_add_lli( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, long long int match_value );
+
+/**
+ * @brief              Adds a condition for calendar_time_s 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_add_operator()
+ */
+API int        calendar_filter_add_caltime( calendar_filter_h filter, unsigned int property_id, calendar_match_int_flag_e match, calendar_time_s match_value );
+
+/**
+ * @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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_add_operator()
+ */
+
+API int calendar_filter_add_filter( calendar_filter_h parent_filter, calendar_filter_h child_filter);
+/**
+ * @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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_filter_add_str()
+ * @see calendar_filter_add_int()
+ * @see calendar_filter_add_bool()
+ */
+API int calendar_filter_add_operator( calendar_filter_h filter, calendar_filter_operator_e operator_type );
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_FILTER_H__ */
+
diff --git a/include/calendar_list.h b/include/calendar_list.h
new file mode 100644 (file)
index 0000000..9ba3a8b
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_LIST_H__
+#define __TIZEN_SOCAIL_CALENDAR_LIST_H__
+
+#include <calendar_types2.h>
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_LIST_MODULE
+ * @{
+ */
+
+/**
+ * @brief Creates a handle to the calendar list.
+ *
+ * @remarks @a calendar_list must be released with calendar_list_destroy() by you.
+ *
+ * @param[out]  calendar_list    The calendar list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_list_destroy()
+ */
+API int calendar_list_create( calendar_list_h* out_list );
+
+/**
+ * @brief Destroys a calendar list handle and releases all its resources.
+ *
+ * @param[in]   calendar_list  The calendar list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                    Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_list_create()
+ */
+API int calendar_list_destroy( calendar_list_h list, bool delete_record );
+
+
+/**
+ * @brief      Retrieves count of calendar entity from a calendar list.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ * @param[out] count                                           The count of calendar entity
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_list_add()
+ */
+API int calendar_list_get_count( calendar_list_h list, int *count );
+
+/**
+ * @brief      Adds a record handle to calendar list handle.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ * @param[in]  record                                          The record handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_list_remove()
+ */
+API int calendar_list_add( calendar_list_h list, calendar_record_h record );
+
+/**
+ * @brief      Removes a record handle to calendar 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]  calendar_list                           The calendar list handle
+ * @param[in]  record                                          The record handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_list_add()
+ */
+API int calendar_list_remove( calendar_list_h list, calendar_record_h record );
+
+/**
+ * @brief              Retrieves a record handle from calendar 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 calendar_list is destroyed.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ * @param[out] record                                          The record handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+API int calendar_list_get_current_record_p( calendar_list_h list, calendar_record_h* record );
+
+/**
+ * @brief              Moves a calendar list to previous position.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_list_next()
+ */
+API int calendar_list_prev( calendar_list_h list );
+
+/**
+ * @brief              Moves a calendar list to next position.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_list_prev()
+ */
+API int calendar_list_next( calendar_list_h list );
+
+/**
+ * @brief              Moves a calendar list to the first position.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_list_last()
+ */
+API int calendar_list_first( calendar_list_h list );
+
+/**
+ * @brief              Moves a calendar lis tto the last position.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_list_first()
+ */
+API int calendar_list_last( calendar_list_h list );
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_LIST_H__ */
+
diff --git a/include/calendar_query.h b/include/calendar_query.h
new file mode 100644 (file)
index 0000000..95c5fe1
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_QUERY_H__
+#define __TIZEN_SOCAIL_CALENDAR_QUERY_H__
+
+#include <calendar_types2.h>
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_QUERY_MODULE
+ * @{
+ */
+
+/**
+ * @brief   Creates a query handle.
+ *
+ * @remarks            @a query must be released with calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY       Out of memory
+ *
+ * @see calendar_filter_destroy()
+ */
+API int calendar_query_create( const char* view_uri, calendar_query_h* query );
+
+/**
+ * @brief   Destroys a query handle.
+ *
+ * @param[in]   query    The query handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_query_create()
+ */
+API int calendar_query_destroy( calendar_query_h query );
+
+/**
+ * @brief              Adds property IDs for projection.
+ *
+ * @param[in]   query                          The query 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+API int calendar_query_set_projection(calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+API int calendar_query_set_distinct(calendar_query_h query, bool set);
+
+/**
+ * @brief              Sets 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_query_add_operator()
+ */
+API int calendar_query_set_filter(calendar_query_h query, calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+API int calendar_query_set_sort(calendar_query_h query, unsigned int property_id, bool is_ascending);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_QUERY_H__ */
+
diff --git a/include/calendar_record.h b/include/calendar_record.h
new file mode 100644 (file)
index 0000000..714b3d3
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_RECORD_H__
+#define __TIZEN_SOCAIL_CALENDAR_RECORD_H__
+
+#include <calendar_types2.h>
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_RECORD_MODULE
+ * @{
+ */
+
+/**
+ * @brief Creates a handle to the record.
+ *
+ * @remarks @a record must be released with calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_destroy()
+ */
+API int calendar_record_create( const char* view_uri, calendar_record_h* out_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  #CALENDAR_ERROR_NONE                    Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_list_create()
+ */
+API int calendar_record_destroy( calendar_record_h record, bool delete_child );
+
+/**
+ * @brief      Makes a clone of a record handle.
+ *
+ * @remarks @a cloned_record must be released with calendar_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  #CALENDAR_ERROR_NONE                    Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_destroy()
+ */
+API int calendar_record_clone( calendar_record_h record, calendar_record_h* out_record );
+
+/**
+ * @brief      Gets uri string from a record handle.
+ *
+ * @param[in]   record                 The record handle
+ * @param[out]  uri                    The uri of record
+ *
+ * @return 0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                 Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER    Invalid parameter
+ */
+API int calendar_record_get_uri_p( calendar_record_h record, char** uri );
+
+/**
+ * @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  #CALENDAR_ERROR_NONE                 Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER    Invalid parameter
+ *
+ * @see calendar_record_get_str_p()
+ * @see calendar_record_set_str()
+ */
+API int calendar_record_get_str( calendar_record_h record, unsigned int property_id, char** out_str );
+
+/**
+ * @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  #CALENDAR_ERROR_NONE                 Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER    Invalid parameter
+ *
+ * @see calendar_record_get_str()
+ * @see calendar_record_set_str()
+ */
+API int calendar_record_get_str_p( calendar_record_h record, unsigned int property_id, char** out_str );
+
+/**
+ * @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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_record_set_int()
+ */
+API int calendar_record_get_int( calendar_record_h record, unsigned int property_id, int* out_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_record_set_double()
+ */
+API int calendar_record_get_double( calendar_record_h record, unsigned int property_id, double* out_value );
+
+/**
+ * @brief   Gets a long 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_record_set_lli()
+ */
+API int calendar_record_get_lli( calendar_record_h record, unsigned int property_id, long long int* out_value );
+
+/**
+ * @brief   Gets a caltime_caltime_s 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_record_set_caltime()
+ */
+API int calendar_record_get_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s* out_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      #CALENDAR_ERROR_NONE                    Successful
+ * @retval      #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_get_str()
+ * @see calendar_record_get_str_p()
+ */
+API int calendar_record_set_str( calendar_record_h record, unsigned int property_id, const char* 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      #CALENDAR_ERROR_NONE                    Successful
+ * @retval      #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_get_double()
+ */
+API int calendar_record_set_int( calendar_record_h record, unsigned int property_id, int value );
+
+/**
+ * @brief   Sets a double 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      #CALENDAR_ERROR_NONE                    Successful
+ * @retval      #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_get_int()
+ */
+API int calendar_record_set_double( calendar_record_h record, unsigned int property_id, double value );
+
+/**
+ * @brief   Sets a long 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      #CALENDAR_ERROR_NONE                    Successful
+ * @retval      #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_get_lli()
+ */
+API int calendar_record_set_lli( calendar_record_h record, unsigned int property_id, long long int value );
+
+/**
+ * @brief   Sets a long calendar_time_s 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      #CALENDAR_ERROR_NONE                    Successful
+ * @retval      #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_get_caltime()
+ */
+API int calendar_record_set_caltime( calendar_record_h record, unsigned int property_id, calendar_time_s 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  #CALENDAR_ERROR_NONE                    Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_remove_child_record()
+ */
+API int calendar_record_add_child_record( calendar_record_h record, unsigned int property_id, calendar_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  #CALENDAR_ERROR_NONE                    Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER       Invalid parameter
+ *
+ * @see calendar_record_add_child_record()
+ */
+API int calendar_record_remove_child_record( calendar_record_h record, unsigned int property_id, calendar_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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @see calendar_record_add_child_record()
+ * @see calendar_record_remove_child_record()
+ */
+API int calendar_record_get_child_record_count( calendar_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  #CALENDAR_ERROR_NONE                 Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER    Invalid parameter
+ *
+ * @see calendar_record_add_child_record()
+ * @see calendar_record_remove_child_record()
+ * @see calendar_record_get_child_record_count()
+ */
+API int calendar_record_get_child_record_at_p( calendar_record_h record, unsigned int property_id, int index, calendar_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 calendar_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  #CALENDAR_ERROR_NONE                 Successful
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER    Invalid parameter
+ *
+ * @see calendar_list_destroy()
+ */
+API int calendar_record_clone_child_record_list( calendar_record_h record, unsigned int property_id, calendar_list_h* out_list );
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_RECORD_H__ */
+
diff --git a/include/calendar_reminder.h b/include/calendar_reminder.h
new file mode 100644 (file)
index 0000000..aa3b843
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_REMINDER_H__
+#define __TIZEN_SOCAIL_CALENDAR_REMINDER_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_REMINDER_MODULE
+ * @{
+ */
+
+/**
+ * @brief   Adds a receiver to get noti when alarm alerts.
+ *
+ * @remarks If failed to run appsvc, added receiver will be removed from the table.
+ *
+ * @param[in]   pkgname                            The package name to add.
+ * @param[in]   extra_data_key         The user defined key to be passed via appsvc.
+ * @param[in]   extra_data_value       THe user defined value to be passed via appsvc.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_reminder_remove_receiver()
+ */
+API int calendar_reminder_add_receiver(const char *pkgname, const char *extra_data_key, const char *extra_data_value);
+
+/**
+ * @brief   Removes a receiver to get noti when alarm alerts.
+ *
+ * @param[in]   pkgname                            The package name to add.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_reminder_remove_receiver()
+ */
+API int calendar_reminder_remove_receiver(const char *pkgname);
+
+/**
+ * @brief   Activates a receiver to get noti when alarm alerts.
+ *
+ * @param[in]   pkgname                            The package name to add.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_reminder_remove_receiver()
+ */
+API int calendar_reminder_activate_receiver(const char *pkgname);
+
+/**
+ * @brief   Deactivates a receiver to get noti when alarm alerts.
+ *
+ * @param[in]   pkgname                            The package name to add.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_reminder_remove_receiver()
+ */
+API int calendar_reminder_deactivate_receiver(const char *pkgname);
+
+/**
+ * @brief   Check whether receiver exist in the table or not.
+ *
+ * @param[in]   pkgname                            The package name to add.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_reminder_remove_receiver()
+ */
+API bool calendar_reminder_has_receiver(const char *pkgname);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_REMINDER_H__ */
+
diff --git a/include/calendar_service.h b/include/calendar_service.h
new file mode 100644 (file)
index 0000000..7054ecd
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_SERVICE_H__
+#define __TIZEN_SOCAIL_CALENDAR_SERVICE_H__
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_DATABASE_MODULE
+ * @{
+ */
+
+/**
+ * @brief      Connects to the calendar service.
+ *
+ * @remarks Connection opening is necessary to access the calendar database such as fetching, inserting, or updating records.\n
+ * The execution of calendar_connect() and calendar_disconnect() could slow down your application so you are recommended not to call them frequently.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE               Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED  Database operation failure
+ *
+ * @see  calendar_disconnect()
+ */
+API int calendar_connect(void);
+
+/**
+ * @brief      Disconnects from the calendar service.
+ *
+ * @remarks    If there is no opened connection, this function returns #CALENDAR_ERROR_DB_FAILED.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE               Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED  Database operation failure
+ *
+ * @see calendar_connect()
+ */
+API int calendar_disconnect(void);
+
+/**
+ * @brief   Connects to the calendar service on thread.
+ *
+ * @remarks Connection opening is necessary to access the calendar database such as fetching, inserting, or updating records.\n
+ * The execution of calendar_connect() and calendar_disconnect() could slow down your application so you are recommended not to call them frequently.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see  calendar_disconnect()
+ */
+API int calendar_connect_on_thread(void);
+
+/**
+ * @brief   Disconnects from the calendar service on thread.
+ *
+ * @remarks If there is no opened connection, this function returns #CALENDAR_ERROR_DB_FAILED.
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see calendar_connect()
+ */
+API int calendar_disconnect_on_thread(void);
+
+/**
+ * @brief   Connects to the calendar service.
+ *
+ * @remarks Connection opening is necessary to access the calendar database such as fetching, inserting, or updating records.\n
+ * The execution of calendar_connect() and calendar_disconnect() could slow down your application so you are recommended not to call them frequently.
+ *
+ * @param[in]   flags  calendar_connect_flag
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE        Successful
+ * @retval  #CALENDAR_ERROR_DB_FAILED   Database operation failure
+ *
+ * @see  calendar_disconnect(), CALENDAR_CONNECT_FLAG_RETRY
+ */
+API int calendar_connect_with_flags(unsigned int flags);
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_SERVICE_H__ */
+
diff --git a/include/calendar_types2.h b/include/calendar_types2.h
new file mode 100644 (file)
index 0000000..1137755
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT 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_CALENDAR_TYPES_H__
+#define __TIZEN_SOCIAL_CALENDAR_TYPES_H__
+
+#include <stdint.h>
+#include <tizen.h>
+#include <calendar_errors.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#define _CALENDAR_HANDLE(A) typedef struct __##A* A;
+
+#define _CALENDAR_BEGIN_VIEW() \
+               typedef struct{ \
+                       const char* _uri;
+#define _CALENDAR_PROPERTY_INT(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_STR(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_DOUBLE(property_id_name)     unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_LLI(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_CALTIME(property_id_name)    unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_CHILD_MULTIPLE(property_id_name) unsigned int property_id_name;
+#define _CALENDAR_END_VIEW(name) } name##_property_ids; \
+    extern API const name##_property_ids name;
+
+#define _CALENDAR_BEGIN_READ_ONLY_VIEW() \
+        typedef struct{ \
+            const char* _uri;
+#define _CALENDAR_PROPERTY_PROJECTION_INT(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_PROJECTION_STR(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_PROJECTION_DOUBLE(property_id_name)     unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_PROJECTION_LLI(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_PROJECTION_CALTIME(property_id_name)    unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_FILTER_INT(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_FILTER_STR(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_FILTER_DOUBLE(property_id_name)     unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_FILTER_LLI(property_id_name)        unsigned int property_id_name;
+#define _CALENDAR_PROPERTY_FILTER_CALTIME(property_id_name)    unsigned int property_id_name;
+#define _CALENDAR_END_READ_ONLY_VIEW(name) } name##_property_ids; \
+    extern API const name##_property_ids name;
+
+_CALENDAR_HANDLE( calendar_record_h )
+_CALENDAR_HANDLE( calendar_filter_h )
+_CALENDAR_HANDLE( calendar_list_h )
+_CALENDAR_HANDLE( calendar_query_h )
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_DATABASE_MODULE
+ * @{
+ */
+
+/**
+ * @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 calendar_db_update_records() will invoke this callback.
+ *
+ * @see calendar_db_update_records()
+ */
+typedef void (*calendar_db_result_cb)( int error, void *user_data);
+
+/**
+ * @brief The callback function to get the result of batch operation.
+ *
+ * @param[in]   error           Error code for batch operation
+ * @param[in]   record_id_array The record IDs for batch operation
+ * @param[in]   count           The number of record ID array
+ * @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 calendar_db_insert_records() will invoke this callback.
+ *
+ * @see calendar_db_insert_records()
+ */
+typedef void (*calendar_db_insert_result_cb)( int error, int* record_id_array, int count, void *user_data);
+
+/**
+ * @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 calendar_db_add_changed_cb()
+ */
+typedef void (*calendar_db_changed_cb)(const char* view_uri, void* user_data);
+
+/**
+ * @brief Definition for calendar connect flag
+ */
+#define CALENDAR_CONNECT_FLAG_NONE         0x00000000
+#define CALENDAR_CONNECT_FLAG_RETRY        0x00000001
+
+/**
+ * @brief Definition for default event calendar book database ID
+ */
+#define DEFAULT_EVENT_CALENDAR_BOOK_ID           1
+
+/**
+ * @brief Definition for default to-do calendar book database ID
+ */
+#define DEFAULT_TODO_CALENDAR_BOOK_ID            2
+
+/**
+ * @brief Definition for default birthday calendar book database ID
+ */
+#define DEFAULT_BIRTHDAY_CALENDAR_BOOK_ID        3
+
+/**
+ * @brief Definition for no due date of a to-do
+ */
+#define CALENDAR_TODO_NO_DUE_DATE   INT64_MAX
+
+/**
+ * @brief Definition for no start date of a to-do
+ */
+#define CALENDAR_TODO_NO_START_DATE (-INT64_MAX)
+
+/**
+ * @brief Definition for no until of a record
+ */
+#define CALENDAR_RECORD_NO_UNTIL    INT64_MAX
+
+/**
+ * @brief Definition for no coordinate(latitude/longitude) of a record
+ */
+#define CALENDAR_RECORD_NO_COORDINATE 1000
+
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_FILTER_MODULE
+ * @{
+ */
+
+/**
+ * @brief Definition for all calendar book
+ */
+#define CALENDAR_BOOK_FILTER_ALL                    -1
+
+/**
+ * @brief Enumerations of filter match type for string
+ */
+typedef enum
+{
+       CALENDAR_MATCH_EXACTLY,                 /**< . */
+       CALENDAR_MATCH_FULLSTRING,              /**< . */
+       CALENDAR_MATCH_CONTAINS,                /**< . */
+       CALENDAR_MATCH_STARTSWITH,              /**< . */
+       CALENDAR_MATCH_ENDSWITH,                /**< . */
+       CALENDAR_MATCH_EXISTS           /**< . */
+} calendar_match_str_flag_e;
+
+/**
+ * @brief Enumerations of filter match type for integer
+ */
+typedef enum
+{
+       CALENDAR_MATCH_EQUAL,                                   /**< . */
+       CALENDAR_MATCH_GREATER_THAN,                    /**< . */
+       CALENDAR_MATCH_GREATER_THAN_OR_EQUAL,   /**< . */
+       CALENDAR_MATCH_LESS_THAN,                               /**< . */
+       CALENDAR_MATCH_LESS_THAN_OR_EQUAL,              /**< . */
+       CALENDAR_MATCH_NOT_EQUAL,               /**< this flag can yield poor performance */
+       CALENDAR_MATCH_NONE                                             /**< . */
+} calendar_match_int_flag_e;
+
+/**
+ * @brief Enumerations of filter combine type
+ */
+typedef enum {
+       CALENDAR_FILTER_OPERATOR_AND,   /**< . */
+       CALENDAR_FILTER_OPERATOR_OR             /**< . */
+} calendar_filter_operator_e;
+
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_RECORD_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumerations for calendar book type. "OR"ing supported.
+ */
+typedef enum
+{
+    CALENDAR_BOOK_TYPE_NONE          = 0,       /**< Calendar book type default */
+    CALENDAR_BOOK_TYPE_EVENT         = 1<<0,        /**< Event calendar book type */
+    CALENDAR_BOOK_TYPE_TODO          = 1<<1     /**< To-do Calendar book type */
+} calendar_book_type_e;
+
+/**
+ * @brief Enumerations for calendar sensitivity type.
+ */
+typedef enum
+{
+    CALENDAR_SENSITIVITY_PUBLIC          = 0,  /**< Public Sensitivity */
+    CALENDAR_SENSITIVITY_PRIVATE,                              /**< Private Sensitivity */
+    CALENDAR_SENSITIVITY_CONFIDENTIAL                  /**< Confidential Sensitivity */
+} calendar_sensitivity_e;
+
+/**
+ * @brief Enumerations of attendee status.
+ */
+typedef enum
+{
+       CALENDAR_ATTENDEE_STATUS_PENDING        = 0,    /**< Pending status */
+       CALENDAR_ATTENDEE_STATUS_ACCEPTED,                      /**< Accepted status */
+       CALENDAR_ATTENDEE_STATUS_DECLINED,                      /**< Decliend status */
+       CALENDAR_ATTENDEE_STATUS_TENTATIVE,                     /**< Tentative status */
+       CALENDAR_ATTENDEE_STATUS_DELEGATED,                     /**< Delegated status */
+       CALENDAR_ATTENDEE_STATUS_COMPLETED,                     /**< Completed status */
+       CALENDAR_ATTENDEE_STATUS_IN_PROCESS,                    /**< In process status */
+       CALENDAR_ATTENDEE_STATUS_MAX,
+}calendar_attendee_status_e;
+
+/**
+ * @brief Enumerations of attendee role.
+ */
+typedef enum
+{
+       CALENDAR_ATTENDEE_ROLE_REQ_PARTICIPANT  = 0,    /**< Participation is required */
+       CALENDAR_ATTENDEE_ROLE_OPT_PARTICIPANT,                 /**< Accepted status */
+       CALENDAR_ATTENDEE_ROLE_NON_PARTICIPANT,                 /**< Non-Participant */
+       CALENDAR_ATTENDEE_ROLE_CHAIR,                                   /**< Chairperson */
+       CALENDAR_ATTENDEE_ROLE_MAX,
+}calendar_attendee_role_e;
+
+/**
+ * @brief  Alarm time unit type of event such as minutes, hours, days, or etc.
+ */
+typedef enum
+{
+    CALENDAR_ALARM_NONE = -1,                  /**< No reminder set */
+    CALENDAR_ALARM_TIME_UNIT_SPECIFIC = 1,     /**< specific in sec */
+    CALENDAR_ALARM_TIME_UNIT_MINUTE = 60,      /**< Alarm time unit in minutes */
+    CALENDAR_ALARM_TIME_UNIT_HOUR = 3600,      /**< Alarm time unit in hours */
+    CALENDAR_ALARM_TIME_UNIT_DAY = 86400,      /**< Alarm time unit in days */
+    CALENDAR_ALARM_TIME_UNIT_WEEK = 604800,    /**< Alarm time unit in weeks */
+    CALENDAR_ALARM_TIME_UNIT_MONTH = 18144000, /**< Alarm time unit in months */
+} calendar_alarm_time_unit_type_e;
+
+/**
+ * @brief Enumerations of the frequency of event recurrence.
+ */
+typedef enum
+{
+    CALENDAR_RECURRENCE_NONE,           /**< No recurrence event */
+    CALENDAR_RECURRENCE_DAILY,          /**< A Event occurs every day */
+    CALENDAR_RECURRENCE_WEEKLY,         /**< A Event occurs on the same day of every week \n According to week flag, the event will recurrence every days of week */
+    CALENDAR_RECURRENCE_MONTHLY,        /**< A Event occurs on the same day of every month */
+    CALENDAR_RECURRENCE_YEARLY         /**< A Event occurs on the same day of every year */
+} calendar_recurrence_frequency_e;
+
+/**
+ * @brief Enumerations of status for event.
+ */
+typedef enum
+{
+    CALENDAR_EVENT_STATUS_NONE         = 0x01,         /**< None */
+    CALENDAR_EVENT_STATUS_TENTATIVE    = 0x02,         /**< The event is tentative */
+    CALENDAR_EVENT_STATUS_CONFIRMED    = 0x04,         /**< The event is confirmed */
+    CALENDAR_EVENT_STATUS_CANCELLED    = 0x08          /**< The event is cancelled */
+}calendar_event_status_e;
+
+/**
+ * @brief Enumerations of busy status for event.
+ */
+typedef enum
+{
+    CALENDAR_EVENT_BUSY_STATUS_FREE = 0,               /**< The free status */
+    CALENDAR_EVENT_BUSY_STATUS_BUSY,                   /**< The busy status */
+    CALENDAR_EVENT_BUSY_STATUS_UNAVAILABLE,            /**< The unavailable status */
+    CALENDAR_EVENT_BUSY_STATUS_TENTATIVE               /**< The tentative status */
+}calendar_event_busy_status_e;
+/**
+ * @brief Calendar event item priority
+ */
+typedef enum
+{
+    CALENDAR_EVENT_PRIORITY_LOW          = 0,  /**< Low priority */
+    CALENDAR_EVENT_PRIORITY_NORMAL,                            /**< Normal priority */
+    CALENDAR_EVENT_PRIORITY_HIGH                               /**< High priority */
+} calendar_event_priority_e;
+
+/**
+ * @brief Calendar to-do item priority
+ */
+typedef enum
+{
+       CALENDAR_TODO_PRIORITY_NONE                     = 0x01, /**< Priority none */
+    CALENDAR_TODO_PRIORITY_LOW          = 0x08,        /**< Low priority */
+    CALENDAR_TODO_PRIORITY_NORMAL              = 0x04, /**< Normal priority */
+    CALENDAR_TODO_PRIORITY_HIGH                        = 0x02, /**< High priority */
+} calendar_todo_priority_e;
+
+/**
+ * @brief Enumerations of status for to-do.
+ */
+typedef enum
+{
+    CALENDAR_TODO_STATUS_NONE                  = 0x0100,       /**< None */
+    CALENDAR_TODO_STATUS_NEEDS_ACTION  = 0x0200,       /**< Needs action status */
+    CALENDAR_TODO_STATUS_COMPLETED             = 0x0400,       /**< Completed status */
+    CALENDAR_TODO_STATUS_IN_PROCESS            = 0x0800,       /**< Work in process status */
+    CALENDAR_TODO_STATUS_CANCELED              = 0x1000        /**< Canceled status */
+} calendar_todo_status_e;
+
+typedef enum
+{
+       CALENDAR_TIME_UTIME = 0,                        /**< . */
+       CALENDAR_TIME_LOCALTIME,                        /**< . */
+} calendar_time_type_e;
+
+typedef enum
+{
+       CALENDAR_RANGE_UNTIL,           /**< . */
+       CALENDAR_RANGE_COUNT,           /**< . */
+       CALENDAR_RANGE_NONE,            /**< . */
+} calendar_range_type_e;
+
+typedef enum
+{
+    CALENDAR_SYSTEM_NONE,                                      /**< . */
+    CALENDAR_SYSTEM_GREGORIAN,                         /**< . */
+    CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR,      /**< . */
+} calendar_system_type_e;
+
+typedef enum
+{
+    CALENDAR_MEETING_STATUS_NOTMEETING = 0,     /**< . */
+    CALENDAR_MEETING_STATUS_MEETING,            /**< . */
+    CALENDAR_MEETING_STATUS_RECEIVED,           /**< . */
+    CALENDAR_MEETING_STATUS_CANCELED,           /**< . */
+} calendar_meeting_status_e;
+
+/**
+ * @brief Enumerations of weekday of month(Same value as UCalendarDaysOfWeek in ICU).
+ */
+typedef enum
+{
+       CALENDAR_SUNDAY = 1,
+       CALENDAR_MONDAY,
+       CALENDAR_TUESDAY,
+       CALENDAR_WEDNESDAY,
+       CALENDAR_THURSDAY,
+       CALENDAR_FRIDAY,
+       CALENDAR_SATURDAY,
+}calendar_days_of_week_e;
+
+// deprecated
+#define CALENDAR_EVENT_MODIFIED_STATUS_INSERTED 0
+#define CALENDAR_EVENT_MODIFIED_STATUS_UPDATED  1
+#define CALENDAR_EVENT_MODIFIED_STATUS_DELETED  2
+/**
+ * @brief Enumerations of modified status for record.
+ */
+typedef enum
+{
+    CALENDAR_RECORD_MODIFIED_STATUS_INSERTED = 0,    /**< The record is inserted */
+    CALENDAR_RECORD_MODIFIED_STATUS_UPDATED,                   /**< The record is updated */
+    CALENDAR_RECORD_MODIFIED_STATUS_DELETED          /**< The record is deleted */
+}calendar_record_modified_status_e;
+
+/**
+ * @brief The structure of time
+ */
+typedef struct
+{
+    calendar_time_type_e type;
+    union {
+        long long int utime;
+        struct {
+            int year;
+            int month;
+            int mday;
+        }date;
+    }time;
+}calendar_time_s;
+
+/**
+ * @brief Enumerations of type for record.
+ */
+typedef enum
+{
+    CALENDAR_RECORD_TYPE_NONE = 0,          /**< . */
+    CALENDAR_RECORD_TYPE_CALENDAR_BOOK,     /**< . */
+    CALENDAR_RECORD_TYPE_EVENT,             /**< . */
+    CALENDAR_RECORD_TYPE_TODO,              /**< . */
+}calendar_record_type_e;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__TIZEN_SOCIAL_CALENDAR_TYPES_H__
diff --git a/include/calendar_vcalendar.h b/include/calendar_vcalendar.h
new file mode 100644 (file)
index 0000000..fe38ff5
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_SOCAIL_CALENDAR_VCALENDAR_H__
+#define __TIZEN_SOCAIL_CALENDAR_VCALENDAR_H__
+
+#include <calendar_view.h>
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_SOCIAL_CALENDAR_SVC_VCALENDAR_MODULE
+ * @{
+ */
+
+/**
+ * @brief      Retrieves vcalendar stream from a calendar list.
+ *
+ * @param[in]  calendar_list                           The calendar list handle
+ * @param[out] vcalendar_stream                        The vcalendar stream
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+API int calendar_vcalendar_make_from_records(calendar_list_h calendar_list, char **vcalendar_stream);
+
+/**
+ * @brief      Retrieves all calendar with calendar list from vcalendar stream.
+ *
+ * @param[in]  vcalendar_stream                        The vcalendar stream
+ * @param[out] calendar_list                           The calendar list handle
+ *
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ */
+API int calendar_vcalendar_parse_to_calendar(const char* vcalendar_stream, calendar_list_h *calendar_list);
+
+/**
+ * @brief The callback function to get record hadle of
+ * \ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_event or \ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_todo.
+ *
+ * @param[in]  record     The record handle (\ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_event or \ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_todo)
+ * @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 calendar_vcalendar_parse_to_calendar_foreach() will invoke this callback.
+ *
+ * @see calendar_vcalendar_parse_to_calendar_foreach()
+ * @see calendar_record_get_uri_p()
+ */
+typedef bool (*calendar_vcalendar_parse_cb)(calendar_record_h record, void *user_data);
+
+/**
+ * @brief      Retrieves all events or to-dos with record handle
+ * (\ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_event or \ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_todo) from a vCalendar file.
+ *
+ * @param[in]  vcalendar_file_path             The file path of vCalendar 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  #CALENDAR_ERROR_NONE                Successful
+ * @retval  #CALENDAR_ERROR_OUT_OF_MEMORY       Out of memory
+ * @retval  #CALENDAR_ERROR_INVALID_PARAMETER   Invalid parameter
+ *
+ * @post This function invokes calendar_vcalendar_parse_cb().
+ *
+ * @see  calendar_vcalendar_parse_cb()
+ * @see  calendar_record_get_uri_p()
+ */
+API int calendar_vcalendar_parse_to_calendar_foreach(const char *vcalendar_file_path, calendar_vcalendar_parse_cb callback, void *user_data);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCAIL_CALENDAR_VCALENDAR_H__ */
+
diff --git a/include/calendar_view.h b/include/calendar_view.h
new file mode 100644 (file)
index 0000000..c7355dd
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT 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_CALENDAR_VIEW_H__
+#define __TIZEN_SOCIAL_CALENDAR_VIEW_H__
+
+#include <calendar_types2.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_CALENDAR_BEGIN_VIEW()
+       _CALENDAR_PROPERTY_INT( id )            // read_only
+       _CALENDAR_PROPERTY_STR( uid )
+       _CALENDAR_PROPERTY_STR( name )
+       _CALENDAR_PROPERTY_STR( description )
+       _CALENDAR_PROPERTY_STR( color )
+       _CALENDAR_PROPERTY_STR( location )
+       _CALENDAR_PROPERTY_INT( visibility )
+       _CALENDAR_PROPERTY_INT( sync_event )
+       _CALENDAR_PROPERTY_INT( is_deleted )
+       _CALENDAR_PROPERTY_INT( account_id )
+       _CALENDAR_PROPERTY_INT( store_type )
+       _CALENDAR_PROPERTY_STR( sync_data1 )
+       _CALENDAR_PROPERTY_STR( sync_data2 )
+       _CALENDAR_PROPERTY_STR( sync_data3 )
+       _CALENDAR_PROPERTY_STR( sync_data4 )
+_CALENDAR_END_VIEW( _calendar_book )
+
+_CALENDAR_BEGIN_VIEW()
+       _CALENDAR_PROPERTY_INT( id )                // read_only
+       _CALENDAR_PROPERTY_INT( calendar_book_id )
+       _CALENDAR_PROPERTY_STR( summary )
+       _CALENDAR_PROPERTY_STR( description )
+       _CALENDAR_PROPERTY_STR( location )
+       _CALENDAR_PROPERTY_STR( categories )
+       _CALENDAR_PROPERTY_STR( exdate )
+       _CALENDAR_PROPERTY_INT( event_status )
+       _CALENDAR_PROPERTY_INT( priority )
+       _CALENDAR_PROPERTY_INT( timezone )
+       _CALENDAR_PROPERTY_INT( person_id )
+       _CALENDAR_PROPERTY_INT( busy_status )
+       _CALENDAR_PROPERTY_INT( sensitivity )
+       _CALENDAR_PROPERTY_STR( uid )
+       _CALENDAR_PROPERTY_STR( organizer_name )
+       _CALENDAR_PROPERTY_STR( organizer_email )
+       _CALENDAR_PROPERTY_INT( meeting_status )
+       _CALENDAR_PROPERTY_INT( original_event_id )
+       _CALENDAR_PROPERTY_DOUBLE( latitude )
+       _CALENDAR_PROPERTY_DOUBLE( longitude )
+       _CALENDAR_PROPERTY_INT( email_id )
+       _CALENDAR_PROPERTY_LLI( created_time )
+       _CALENDAR_PROPERTY_LLI( last_modified_time )
+       _CALENDAR_PROPERTY_INT( is_deleted )        // read_only
+       _CALENDAR_PROPERTY_INT( freq )
+       _CALENDAR_PROPERTY_INT( range_type )
+       _CALENDAR_PROPERTY_CALTIME( until_time )
+       _CALENDAR_PROPERTY_INT( count )
+       _CALENDAR_PROPERTY_INT( interval )
+       _CALENDAR_PROPERTY_STR( bysecond )
+       _CALENDAR_PROPERTY_STR( byminute )
+       _CALENDAR_PROPERTY_STR( byhour )
+       _CALENDAR_PROPERTY_STR( byday )
+       _CALENDAR_PROPERTY_STR( bymonthday )
+       _CALENDAR_PROPERTY_STR( byyearday )
+       _CALENDAR_PROPERTY_STR( byweekno )
+       _CALENDAR_PROPERTY_STR( bymonth )
+       _CALENDAR_PROPERTY_STR( bysetpos )
+       _CALENDAR_PROPERTY_INT( wkst )
+       _CALENDAR_PROPERTY_STR( recurrence_id )
+       _CALENDAR_PROPERTY_STR( rdate )
+       _CALENDAR_PROPERTY_INT( has_attendee )      // read_only
+       _CALENDAR_PROPERTY_INT( has_alarm )         // read_only
+       _CALENDAR_PROPERTY_INT( calendar_system_type )
+       _CALENDAR_PROPERTY_STR( sync_data1 )
+       _CALENDAR_PROPERTY_STR( sync_data2 )
+       _CALENDAR_PROPERTY_STR( sync_data3 )
+       _CALENDAR_PROPERTY_STR( sync_data4 )
+       _CALENDAR_PROPERTY_CALTIME( start_time )
+       _CALENDAR_PROPERTY_STR( start_tzid )
+       _CALENDAR_PROPERTY_CALTIME( end_time )
+       _CALENDAR_PROPERTY_STR( end_tzid )
+       _CALENDAR_PROPERTY_CHILD_MULTIPLE( calendar_alarm )
+       _CALENDAR_PROPERTY_CHILD_MULTIPLE( calendar_attendee )
+       _CALENDAR_PROPERTY_CHILD_MULTIPLE( exception )
+       _CALENDAR_PROPERTY_CHILD_MULTIPLE( extended )
+       _CALENDAR_PROPERTY_INT( is_allday )         // read only
+_CALENDAR_END_VIEW( _calendar_event )
+
+_CALENDAR_BEGIN_VIEW()
+       _CALENDAR_PROPERTY_INT( id )            // read_only
+       _CALENDAR_PROPERTY_INT( calendar_book_id )
+       _CALENDAR_PROPERTY_STR( summary )
+       _CALENDAR_PROPERTY_STR( description )
+       _CALENDAR_PROPERTY_STR( location )
+       _CALENDAR_PROPERTY_STR( categories )
+       _CALENDAR_PROPERTY_INT( todo_status )
+       _CALENDAR_PROPERTY_INT( priority )
+       _CALENDAR_PROPERTY_INT( sensitivity )
+       _CALENDAR_PROPERTY_STR( uid )
+       _CALENDAR_PROPERTY_DOUBLE( latitude )
+       _CALENDAR_PROPERTY_DOUBLE( longitude )
+       _CALENDAR_PROPERTY_LLI( created_time )
+       _CALENDAR_PROPERTY_LLI( last_modified_time )
+       _CALENDAR_PROPERTY_LLI( completed_time )
+       _CALENDAR_PROPERTY_INT( progress )
+       _CALENDAR_PROPERTY_INT( is_deleted )    // read_only
+       _CALENDAR_PROPERTY_INT( freq )
+       _CALENDAR_PROPERTY_INT( range_type )
+       _CALENDAR_PROPERTY_CALTIME( until_time )
+       _CALENDAR_PROPERTY_INT( count )
+       _CALENDAR_PROPERTY_INT( interval )
+       _CALENDAR_PROPERTY_STR( bysecond )
+       _CALENDAR_PROPERTY_STR( byminute )
+       _CALENDAR_PROPERTY_STR( byhour )
+       _CALENDAR_PROPERTY_STR( byday )
+       _CALENDAR_PROPERTY_STR( bymonthday )
+       _CALENDAR_PROPERTY_STR( byyearday )
+       _CALENDAR_PROPERTY_STR( byweekno )
+       _CALENDAR_PROPERTY_STR( bymonth )
+       _CALENDAR_PROPERTY_STR( bysetpos )
+       _CALENDAR_PROPERTY_INT( wkst )
+       _CALENDAR_PROPERTY_INT( has_alarm )     // read_only
+       _CALENDAR_PROPERTY_STR( sync_data1 )
+       _CALENDAR_PROPERTY_STR( sync_data2 )
+       _CALENDAR_PROPERTY_STR( sync_data3 )
+       _CALENDAR_PROPERTY_STR( sync_data4 )
+       _CALENDAR_PROPERTY_CALTIME( start_time )
+       _CALENDAR_PROPERTY_STR( start_tzid )
+       _CALENDAR_PROPERTY_CALTIME( due_time )
+       _CALENDAR_PROPERTY_STR( due_tzid )
+       _CALENDAR_PROPERTY_CHILD_MULTIPLE( calendar_alarm )
+    _CALENDAR_PROPERTY_STR( organizer_name )
+    _CALENDAR_PROPERTY_STR( organizer_email )
+    _CALENDAR_PROPERTY_INT( has_attendee )     // read_only
+    _CALENDAR_PROPERTY_CHILD_MULTIPLE( calendar_attendee )
+    _CALENDAR_PROPERTY_CHILD_MULTIPLE( extended )
+    _CALENDAR_PROPERTY_INT( is_allday )         // read only
+_CALENDAR_END_VIEW( _calendar_todo )
+
+_CALENDAR_BEGIN_VIEW()
+       _CALENDAR_PROPERTY_INT( id )                    // read_only
+       _CALENDAR_PROPERTY_INT( calendar_book_id )
+       _CALENDAR_PROPERTY_INT( tz_offset_from_gmt ) // offset(minute)
+       _CALENDAR_PROPERTY_STR( standard_name )
+       _CALENDAR_PROPERTY_INT( standard_start_month )
+       _CALENDAR_PROPERTY_INT( standard_start_position_of_week ) // nth wday
+       _CALENDAR_PROPERTY_INT( standard_start_day ) // wday
+       _CALENDAR_PROPERTY_INT( standard_start_hour )
+       _CALENDAR_PROPERTY_INT( standard_bias )
+       _CALENDAR_PROPERTY_STR( day_light_name )
+       _CALENDAR_PROPERTY_INT( day_light_start_month )
+       _CALENDAR_PROPERTY_INT( day_light_start_position_of_week )
+       _CALENDAR_PROPERTY_INT( day_light_start_day )
+       _CALENDAR_PROPERTY_INT( day_light_start_hour )
+       _CALENDAR_PROPERTY_INT( day_light_bias ) // diff between standard and daylight(minute)
+_CALENDAR_END_VIEW( _calendar_timezone )
+
+_CALENDAR_BEGIN_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+       _CALENDAR_PROPERTY_STR( number )
+       _CALENDAR_PROPERTY_INT( type )
+       _CALENDAR_PROPERTY_INT( person_id )
+       _CALENDAR_PROPERTY_STR( uid )
+       _CALENDAR_PROPERTY_STR( group )
+       _CALENDAR_PROPERTY_STR( email )
+       _CALENDAR_PROPERTY_INT( role )
+       _CALENDAR_PROPERTY_INT( status )
+       _CALENDAR_PROPERTY_INT( rsvp )
+       _CALENDAR_PROPERTY_STR( delegate_uri )
+       _CALENDAR_PROPERTY_STR( delegator_uri )
+       _CALENDAR_PROPERTY_STR( name )
+_CALENDAR_END_VIEW( _calendar_attendee )
+
+_CALENDAR_BEGIN_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+    _CALENDAR_PROPERTY_INT( todo_id )
+       _CALENDAR_PROPERTY_INT( type )
+       _CALENDAR_PROPERTY_LLI( time )
+       _CALENDAR_PROPERTY_INT( tick )
+       _CALENDAR_PROPERTY_INT( tick_unit )
+       _CALENDAR_PROPERTY_STR( tone )
+       _CALENDAR_PROPERTY_STR( description )
+       _CALENDAR_PROPERTY_INT( alarm_id )
+_CALENDAR_END_VIEW( _calendar_alarm )
+
+_CALENDAR_BEGIN_READ_ONLY_VIEW()
+       _CALENDAR_PROPERTY_INT( id )
+       _CALENDAR_PROPERTY_INT( calendar_book_id )
+       _CALENDAR_PROPERTY_INT( modified_status )
+       _CALENDAR_PROPERTY_INT( version )
+_CALENDAR_END_READ_ONLY_VIEW( _calendar_updated_info )
+
+_CALENDAR_BEGIN_READ_ONLY_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+    _CALENDAR_PROPERTY_INT( calendar_book_id )
+    _CALENDAR_PROPERTY_STR( summary )
+    _CALENDAR_PROPERTY_STR( description )
+    _CALENDAR_PROPERTY_STR( location )
+    _CALENDAR_PROPERTY_STR( categories )
+    _CALENDAR_PROPERTY_STR( exdate )
+    _CALENDAR_PROPERTY_INT( event_status )
+    _CALENDAR_PROPERTY_INT( priority )
+    _CALENDAR_PROPERTY_INT( timezone )
+    _CALENDAR_PROPERTY_INT( person_id )
+    _CALENDAR_PROPERTY_INT( busy_status )
+    _CALENDAR_PROPERTY_INT( sensitivity )
+    _CALENDAR_PROPERTY_STR( uid )
+    _CALENDAR_PROPERTY_STR( organizer_name )
+    _CALENDAR_PROPERTY_STR( organizer_email )
+    _CALENDAR_PROPERTY_INT( meeting_status )
+    _CALENDAR_PROPERTY_INT( original_event_id )
+    _CALENDAR_PROPERTY_DOUBLE( latitude )
+    _CALENDAR_PROPERTY_DOUBLE( longitude )
+    _CALENDAR_PROPERTY_INT( email_id )
+    _CALENDAR_PROPERTY_LLI( created_time )
+    _CALENDAR_PROPERTY_LLI( last_modified_time )
+    _CALENDAR_PROPERTY_INT( is_deleted )
+    _CALENDAR_PROPERTY_INT( freq )
+    _CALENDAR_PROPERTY_INT( range_type )
+    _CALENDAR_PROPERTY_CALTIME( until_time )
+    _CALENDAR_PROPERTY_INT( count )
+    _CALENDAR_PROPERTY_INT( interval )
+    _CALENDAR_PROPERTY_STR( bysecond )
+    _CALENDAR_PROPERTY_STR( byminute )
+    _CALENDAR_PROPERTY_STR( byhour )
+    _CALENDAR_PROPERTY_STR( byday )
+    _CALENDAR_PROPERTY_STR( bymonthday )
+    _CALENDAR_PROPERTY_STR( byyearday )
+    _CALENDAR_PROPERTY_STR( byweekno )
+    _CALENDAR_PROPERTY_STR( bymonth )
+    _CALENDAR_PROPERTY_STR( bysetpos )
+    _CALENDAR_PROPERTY_INT( wkst )
+    _CALENDAR_PROPERTY_STR( recurrence_id )
+    _CALENDAR_PROPERTY_STR( rdate )
+    _CALENDAR_PROPERTY_INT( has_attendee )
+    _CALENDAR_PROPERTY_INT( has_alarm )
+    _CALENDAR_PROPERTY_INT( calendar_system_type )
+    _CALENDAR_PROPERTY_STR( sync_data1 )
+    _CALENDAR_PROPERTY_STR( sync_data2 )
+    _CALENDAR_PROPERTY_STR( sync_data3 )
+    _CALENDAR_PROPERTY_STR( sync_data4 )
+    _CALENDAR_PROPERTY_CALTIME( start_time )
+    _CALENDAR_PROPERTY_STR( start_tzid )
+    _CALENDAR_PROPERTY_CALTIME( end_time )
+    _CALENDAR_PROPERTY_STR( end_tzid )
+    _CALENDAR_PROPERTY_INT( is_allday )         // read only
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_visibility )
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_account_id )
+_CALENDAR_END_READ_ONLY_VIEW( _calendar_event_calendar_book )
+
+_CALENDAR_BEGIN_READ_ONLY_VIEW()
+    _CALENDAR_PROPERTY_INT( todo_id )
+    _CALENDAR_PROPERTY_INT( calendar_book_id )
+    _CALENDAR_PROPERTY_STR( summary )
+    _CALENDAR_PROPERTY_STR( description )
+    _CALENDAR_PROPERTY_STR( location )
+    _CALENDAR_PROPERTY_STR( categories )
+    _CALENDAR_PROPERTY_INT( todo_status )
+    _CALENDAR_PROPERTY_INT( priority )
+    _CALENDAR_PROPERTY_INT( sensitivity )
+    _CALENDAR_PROPERTY_STR( uid )
+    _CALENDAR_PROPERTY_DOUBLE( latitude )
+    _CALENDAR_PROPERTY_DOUBLE( longitude )
+    _CALENDAR_PROPERTY_LLI( created_time )
+    _CALENDAR_PROPERTY_LLI( last_modified_time )
+    _CALENDAR_PROPERTY_LLI( completed_time )
+    _CALENDAR_PROPERTY_INT( progress )
+    _CALENDAR_PROPERTY_INT( is_deleted )
+    _CALENDAR_PROPERTY_INT( freq )
+    _CALENDAR_PROPERTY_INT( range_type )
+    _CALENDAR_PROPERTY_CALTIME( until_time )
+    _CALENDAR_PROPERTY_INT( count )
+    _CALENDAR_PROPERTY_INT( interval )
+    _CALENDAR_PROPERTY_STR( bysecond )
+    _CALENDAR_PROPERTY_STR( byminute )
+    _CALENDAR_PROPERTY_STR( byhour )
+    _CALENDAR_PROPERTY_STR( byday )
+    _CALENDAR_PROPERTY_STR( bymonthday )
+    _CALENDAR_PROPERTY_STR( byyearday )
+    _CALENDAR_PROPERTY_STR( byweekno )
+    _CALENDAR_PROPERTY_STR( bymonth )
+    _CALENDAR_PROPERTY_STR( bysetpos )
+    _CALENDAR_PROPERTY_INT( wkst )
+    _CALENDAR_PROPERTY_INT( has_alarm )
+    _CALENDAR_PROPERTY_STR( sync_data1 )
+    _CALENDAR_PROPERTY_STR( sync_data2 )
+    _CALENDAR_PROPERTY_STR( sync_data3 )
+    _CALENDAR_PROPERTY_STR( sync_data4 )
+    _CALENDAR_PROPERTY_CALTIME( start_time )
+    _CALENDAR_PROPERTY_STR( start_tzid )
+    _CALENDAR_PROPERTY_CALTIME( due_time )
+    _CALENDAR_PROPERTY_STR( due_tzid )
+    _CALENDAR_PROPERTY_STR( organizer_name )
+    _CALENDAR_PROPERTY_STR( organizer_email )
+    _CALENDAR_PROPERTY_INT( has_attendee )
+    _CALENDAR_PROPERTY_INT( is_allday )         // read only
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_visibility )
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_account_id )
+_CALENDAR_END_READ_ONLY_VIEW( _calendar_todo_calendar_book )
+
+_CALENDAR_BEGIN_READ_ONLY_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+    _CALENDAR_PROPERTY_INT( calendar_book_id )
+    _CALENDAR_PROPERTY_STR( summary )
+    _CALENDAR_PROPERTY_STR( description )
+    _CALENDAR_PROPERTY_STR( location )
+    _CALENDAR_PROPERTY_STR( categories )
+    _CALENDAR_PROPERTY_STR( exdate )
+    _CALENDAR_PROPERTY_INT( event_status )
+    _CALENDAR_PROPERTY_INT( priority )
+    _CALENDAR_PROPERTY_INT( timezone )
+    _CALENDAR_PROPERTY_INT( person_id )
+    _CALENDAR_PROPERTY_INT( busy_status )
+    _CALENDAR_PROPERTY_INT( sensitivity )
+    _CALENDAR_PROPERTY_STR( uid )
+    _CALENDAR_PROPERTY_STR( organizer_name )
+    _CALENDAR_PROPERTY_STR( organizer_email )
+    _CALENDAR_PROPERTY_INT( meeting_status )
+    _CALENDAR_PROPERTY_INT( original_event_id )
+    _CALENDAR_PROPERTY_DOUBLE( latitude )
+    _CALENDAR_PROPERTY_DOUBLE( longitude )
+    _CALENDAR_PROPERTY_INT( email_id )
+    _CALENDAR_PROPERTY_LLI( created_time )
+    _CALENDAR_PROPERTY_LLI( last_modified_time )
+    _CALENDAR_PROPERTY_INT( is_deleted )
+    _CALENDAR_PROPERTY_INT( freq )
+    _CALENDAR_PROPERTY_INT( range_type )
+    _CALENDAR_PROPERTY_CALTIME( until_time )
+    _CALENDAR_PROPERTY_INT( count )
+    _CALENDAR_PROPERTY_INT( interval )
+    _CALENDAR_PROPERTY_STR( bysecond )
+    _CALENDAR_PROPERTY_STR( byminute )
+    _CALENDAR_PROPERTY_STR( byhour )
+    _CALENDAR_PROPERTY_STR( byday )
+    _CALENDAR_PROPERTY_STR( bymonthday )
+    _CALENDAR_PROPERTY_STR( byyearday )
+    _CALENDAR_PROPERTY_STR( byweekno )
+    _CALENDAR_PROPERTY_STR( bymonth )
+    _CALENDAR_PROPERTY_STR( bysetpos )
+    _CALENDAR_PROPERTY_INT( wkst )
+    _CALENDAR_PROPERTY_STR( recurrence_id )
+    _CALENDAR_PROPERTY_STR( rdate )
+    _CALENDAR_PROPERTY_INT( has_attendee )
+    _CALENDAR_PROPERTY_INT( has_alarm )
+    _CALENDAR_PROPERTY_INT( calendar_system_type )
+    _CALENDAR_PROPERTY_STR( sync_data1 )
+    _CALENDAR_PROPERTY_STR( sync_data2 )
+    _CALENDAR_PROPERTY_STR( sync_data3 )
+    _CALENDAR_PROPERTY_STR( sync_data4 )
+    _CALENDAR_PROPERTY_CALTIME( start_time )
+    _CALENDAR_PROPERTY_STR( start_tzid )
+    _CALENDAR_PROPERTY_CALTIME( end_time )
+    _CALENDAR_PROPERTY_STR( end_tzid )
+    _CALENDAR_PROPERTY_INT( is_allday )         // read only
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_visibility )
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_account_id )
+    _CALENDAR_PROPERTY_FILTER_STR( attendee_email )
+    _CALENDAR_PROPERTY_FILTER_STR( attendee_name )
+_CALENDAR_END_READ_ONLY_VIEW( _calendar_event_calendar_book_attendee )
+
+_CALENDAR_BEGIN_READ_ONLY_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+    _CALENDAR_PROPERTY_CALTIME( start_time )
+    _CALENDAR_PROPERTY_CALTIME( end_time )
+    _CALENDAR_PROPERTY_STR( summary )
+    _CALENDAR_PROPERTY_STR( location )
+    _CALENDAR_PROPERTY_INT( calendar_book_id )
+    _CALENDAR_PROPERTY_STR( description )
+    _CALENDAR_PROPERTY_INT( busy_status )
+    _CALENDAR_PROPERTY_INT( event_status )
+    _CALENDAR_PROPERTY_INT( priority )
+    _CALENDAR_PROPERTY_INT( sensitivity )
+    _CALENDAR_PROPERTY_INT( has_rrule )
+    _CALENDAR_PROPERTY_DOUBLE( latitude )
+    _CALENDAR_PROPERTY_DOUBLE( longitude )
+    _CALENDAR_PROPERTY_INT( has_alarm )
+    _CALENDAR_PROPERTY_INT( original_event_id )
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_visibility )
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_account_id )
+    _CALENDAR_PROPERTY_LLI( last_modified_time )
+_CALENDAR_END_READ_ONLY_VIEW( _calendar_instance_normal_calendar_book )
+
+_CALENDAR_BEGIN_READ_ONLY_VIEW()
+    _CALENDAR_PROPERTY_INT( event_id )
+    _CALENDAR_PROPERTY_CALTIME( start_time )
+    _CALENDAR_PROPERTY_CALTIME( end_time )
+    _CALENDAR_PROPERTY_STR( summary )
+    _CALENDAR_PROPERTY_STR( location )
+    _CALENDAR_PROPERTY_INT( calendar_book_id )
+    _CALENDAR_PROPERTY_STR( description )
+    _CALENDAR_PROPERTY_INT( busy_status )
+    _CALENDAR_PROPERTY_INT( event_status )
+    _CALENDAR_PROPERTY_INT( priority )
+    _CALENDAR_PROPERTY_INT( sensitivity )
+    _CALENDAR_PROPERTY_INT( has_rrule )
+    _CALENDAR_PROPERTY_DOUBLE( latitude )
+    _CALENDAR_PROPERTY_DOUBLE( longitude )
+    _CALENDAR_PROPERTY_INT( has_alarm )
+    _CALENDAR_PROPERTY_INT( original_event_id )
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_visibility )
+    _CALENDAR_PROPERTY_FILTER_INT( calendar_book_account_id )
+    _CALENDAR_PROPERTY_LLI( last_modified_time )
+_CALENDAR_END_READ_ONLY_VIEW( _calendar_instance_allday_calendar_book )
+
+_CALENDAR_BEGIN_VIEW()
+    _CALENDAR_PROPERTY_INT( id )
+    _CALENDAR_PROPERTY_INT( record_id )
+    _CALENDAR_PROPERTY_INT( record_type )
+    _CALENDAR_PROPERTY_STR( key )
+    _CALENDAR_PROPERTY_STR( value )
+_CALENDAR_END_VIEW( _calendar_extended_property )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_SOCIAL_CALENDAR_VIEW_H__ */
diff --git a/native/CMakeLists.txt b/native/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..ccdb324
--- /dev/null
@@ -0,0 +1,83 @@
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/native)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common)
+LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
+
+SET(INC_DIR ${CMAKE_SOURCE_DIR}/include)
+
+SET(CALSVCNATIVE calendar-service-native)
+
+SET(SRCS
+       ${CMAKE_SOURCE_DIR}/common/cal_record.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_calendar.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_event.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_todo.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_attendee.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_alarm.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_search.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_timezone.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_updated_info.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_instance_normal.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_instance_allday.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_extended.c
+       ${CMAKE_SOURCE_DIR}/common/cal_view.c
+       ${CMAKE_SOURCE_DIR}/common/cal_filter.c
+       ${CMAKE_SOURCE_DIR}/common/cal_query.c
+       ${CMAKE_SOURCE_DIR}/common/cal_inotify.c
+       ${CMAKE_SOURCE_DIR}/common/cal_list.c
+       ${CMAKE_SOURCE_DIR}/common/cal_time.cpp
+       ${CMAKE_SOURCE_DIR}/common/cal_vcalendar.c
+       ${CMAKE_SOURCE_DIR}/common/cal_vcalendar_make.c
+       ${CMAKE_SOURCE_DIR}/common/cal_vcalendar_parse.c
+       ${CMAKE_SOURCE_DIR}/common/cal_mutex.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db.c
+       ${CMAKE_SOURCE_DIR}/native/cal_calendar.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_util.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_alarm.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_attendee.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_instance.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_rrule.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_query.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_calendar.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_event.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_search.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_timezone.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_instance_normal.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_instance_allday.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_todo.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_extended.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_extended.c
+       ${CMAKE_SOURCE_DIR}/native/cal_reminder.c
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(servicenative_pkgs REQUIRED db-util appsvc alarm-service capi-base-common)
+
+FOREACH(flag ${servicenative_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+
+SET(servicenative_pkgs_LDFLAGS "${pkgs_LDFLAGS} ${servicenative_pkgs_LDFLAGS}")
+
+ADD_DEFINITIONS("-DCAL_NATIVE")
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+#SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_LIBRARY(${CALSVCNATIVE} SHARED ${SRCS})
+SET_TARGET_PROPERTIES(${CALSVCNATIVE} PROPERTIES SOVERSION ${VERSION_MAJOR})
+SET_TARGET_PROPERTIES(${CALSVCNATIVE} PROPERTIES VERSION ${VERSION})
+TARGET_LINK_LIBRARIES(${CALSVCNATIVE} ${servicenative_pkgs_LDFLAGS})
+
+INSTALL(TARGETS ${CALSVCNATIVE} DESTINATION lib)
+INSTALL(FILES ${CALSVCNATIVE}.pc DESTINATION lib/pkgconfig)
+#INSTALL(FILES calendar-service2.pc DESTINATION lib/pkgconfig)
+
+#header
+FILE(GLOB HEADER_FILES ${INC_DIR}/calendar*.h)
+INSTALL(FILES ${HEADER_FILES} DESTINATION include/calendar-service-native)
+
+
diff --git a/native/cal_calendar.c b/native/cal_calendar.c
new file mode 100644 (file)
index 0000000..de5d036
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <glib.h>
+#include <glib-object.h>
+#include <db-util.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_db.h"
+#include "cal_view.h"
+
+#ifdef CAL_NATIVE
+#include "cal_inotify.h"
+#endif
+
+static TLS int db_ref_cnt = 0;
+
+API int calendar_connect(void)
+{
+       CAL_FN_CALL;
+       int ret = 0;
+
+       DBG("pthread_self=%x, db_ref_cnt=%p", pthread_self(),&db_ref_cnt );
+
+       g_type_init();  // added for alarmmgr
+
+       if(db_ref_cnt <= 0)
+       {
+               ret = _cal_db_open();
+               retvm_if(ret, ret, "cal_db_open() Failed(%d)", ret);
+
+               db_ref_cnt = 0;
+#ifdef CAL_NATIVE
+               _cal_inotify_initialize();
+#endif
+       }
+       db_ref_cnt++;
+
+       _cal_view_initialize();
+
+    DBG("db_ref_cnt(%d)", db_ref_cnt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_disconnect(void)
+{
+       CAL_FN_CALL;
+
+    DBG("db_ref_cnt(%d)", db_ref_cnt);
+    DBG("pthread_self=%x, db_ref_cnt=%p", pthread_self(),&db_ref_cnt );
+
+       retvm_if(0 == db_ref_cnt, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Calendar service was not connected");
+
+       if (db_ref_cnt==1) {
+               _cal_db_close();
+
+               db_ref_cnt = 0;
+
+#ifdef CAL_NATIVE
+               _cal_inotify_finalize();
+#endif
+
+               _cal_view_finalize();
+               return CALENDAR_ERROR_NONE;
+       }
+       db_ref_cnt--;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+#ifdef CAL_NATIVE
+API int calendar_db_add_changed_cb(const char* view_uri, calendar_db_changed_cb callback, void* user_data )
+{
+    CAL_FN_CALL;
+    int ret;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    retv_if(NULL == view_uri || NULL == callback , CALENDAR_ERROR_INVALID_PARAMETER);
+
+    type = _cal_view_get_type(view_uri);
+
+    switch(type)
+    {
+    case CAL_RECORD_TYPE_CALENDAR:
+        ret = _cal_inotify_subscribe(CAL_NOTI_TYPE_CALENDAR, CAL_NOTI_CALENDAR_CHANGED, callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_EVENT:
+        ret = _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_TODO:
+        ret = _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, user_data);
+        break;
+    default:
+        ERR("Invalid view_uri(%s)", view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    retvm_if(CALENDAR_ERROR_NONE != ret, ret, "_cal_inotify_subscribe() Failed(%d)", ret);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_remove_changed_cb( const char* view_uri, calendar_db_changed_cb callback, void* user_data )
+{
+    CAL_FN_CALL;
+    int ret;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    retv_if(NULL == view_uri || NULL == callback , CALENDAR_ERROR_INVALID_PARAMETER);
+
+    type = _cal_view_get_type(view_uri);
+
+    switch(type)
+    {
+    case CAL_RECORD_TYPE_CALENDAR:
+        ret = _cal_inotify_unsubscribe_with_data(CAL_NOTI_CALENDAR_CHANGED,
+                               callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_EVENT:
+        ret = _cal_inotify_unsubscribe_with_data(CAL_NOTI_EVENT_CHANGED,
+                               callback, user_data);
+        break;
+    case CAL_RECORD_TYPE_TODO:
+        ret = _cal_inotify_unsubscribe_with_data(CAL_NOTI_TODO_CHANGED,
+                               callback, user_data);
+        break;
+    default:
+        ERR("Invalid view_uri(%s)", view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    retvm_if(CALENDAR_ERROR_NONE != ret, ret, "_cal_inotify_unsubscribe_with_data() Failed(%d)", ret);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_connect_on_thread(void)
+{
+    CAL_FN_CALL;
+    int ret = 0;
+
+    DBG("pthread_self=%x, db_ref_cnt=%p", pthread_self(),&db_ref_cnt );
+
+    g_type_init();  // added for alarmmgr
+
+    if(db_ref_cnt <= 0)
+    {
+        ret = _cal_db_open();
+        retvm_if(ret, ret, "cal_db_open() Failed(%d)", ret);
+
+        db_ref_cnt = 0;
+        _cal_inotify_initialize();
+
+    }
+    db_ref_cnt++;
+
+    _cal_view_initialize();
+
+    DBG("db_ref_cnt(%d)", db_ref_cnt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_disconnect_on_thread(void)
+{
+    CAL_FN_CALL;
+
+    DBG("db_ref_cnt(%d)", db_ref_cnt);
+    DBG("pthread_self=%x, db_ref_cnt=%p", pthread_self(),&db_ref_cnt );
+
+    retvm_if(0 == db_ref_cnt, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Calendar service was not connected");
+
+    if (db_ref_cnt==1) {
+        _cal_db_close();
+
+        db_ref_cnt = 0;
+
+        _cal_inotify_finalize();
+
+        _cal_view_finalize();
+        return CALENDAR_ERROR_NONE;
+    }
+    db_ref_cnt--;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_connect_with_flags(unsigned int flags)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    ret = calendar_connect();
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (flags & CALENDAR_CONNECT_FLAG_RETRY)
+        {
+            int retry_time = 500;
+            int i = 0;
+            for(i=0;i<6;i++)
+            {
+                usleep(retry_time*1000);
+                ret = calendar_connect();
+                DBG("retry cnt=%d, ret=%x",(i+1), ret);
+                if (ret == CALENDAR_ERROR_NONE)
+                    break;
+                retry_time *= 2;
+            }
+
+        }
+    }
+
+    return ret;
+}
+#endif
diff --git a/native/cal_db.c b/native/cal_db.c
new file mode 100644 (file)
index 0000000..695e6d3
--- /dev/null
@@ -0,0 +1,1650 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <db-util.h>
+
+#include "calendar_db.h"
+#include "calendar_vcalendar.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+#include "cal_db_util.h"
+#include "cal_list.h"
+
+#include "cal_db.h"
+
+/*
+ * Declear DB plugin
+ */
+extern cal_db_plugin_cb_s _cal_db_calendar_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_event_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_instance_normal_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_instance_allday_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_todo_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_alarm_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_attendee_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_search_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_timezone_plugin_cb;
+extern cal_db_plugin_cb_s _cal_db_extended_plugin_cb;
+
+static cal_db_plugin_cb_s* __cal_db_get_plugin(cal_record_type_e type);
+
+static void __cal_db_initialize_view_table(void);
+
+#ifdef CAL_NATIVE
+typedef struct {
+    calendar_list_h list;
+    calendar_db_insert_result_cb callback;
+    void *user_data;
+} __insert_records_data_s;
+
+typedef struct {
+    calendar_list_h list;
+    calendar_db_result_cb callback;
+    void *user_data;
+} __update_records_data_s;
+
+typedef struct {
+    const char* view_uri;
+    int *ids;
+    int count;
+    calendar_db_result_cb callback;
+    void *user_data;
+} __delete_records_data_s;
+
+typedef struct {
+    char* vcalendar_stream;
+    calendar_db_insert_result_cb callback;
+    void *user_data;
+} __insert_vcalendars_data_s;
+
+typedef struct {
+    char* vcalendar_stream;
+    int *ids;
+    int count;
+    calendar_db_result_cb callback;
+    void *user_data;
+} __replace_vcalendars_data_s;
+
+typedef struct {
+    calendar_list_h list;
+    int *ids;
+    int count;
+    calendar_db_result_cb callback;
+    void *user_data;
+} __replace_records_data_s;
+static gboolean  __cal_db_insert_records_idle(void* user_data);
+static gboolean  __cal_db_update_records_idle(void* user_data);
+static gboolean  __cal_db_delete_records_idle(void* user_data);
+static gboolean  __cal_db_insert_vcalendars_idle(void* user_data);
+static gboolean  __cal_db_replace_vcalendars_idle(void* user_data);
+static gboolean  __cal_db_replace_records_idle(void* user_data);
+
+static gboolean  __cal_db_insert_records_idle(void* user_data)
+{
+    __insert_records_data_s* callback_data = user_data;
+    int ret = CALENDAR_ERROR_NONE;
+    int *ids = NULL;
+    int count = 0;
+
+    if (callback_data == NULL)
+    {
+        ERR("data is NULL");
+        return false;
+    }
+
+    ret = calendar_db_insert_records(callback_data->list, &ids, &count);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        callback_data->callback(ret, ids, count, callback_data->user_data);
+    }
+    else
+    {
+        callback_data->callback(ret, NULL, 0, callback_data->user_data);
+    }
+
+    calendar_list_destroy(callback_data->list, true);
+    CAL_FREE(callback_data);
+    CAL_FREE(ids);
+    return false;
+}
+
+static gboolean  __cal_db_update_records_idle(void* user_data)
+{
+    __update_records_data_s* callback_data = user_data;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (callback_data == NULL)
+    {
+        ERR("data is NULL");
+        return false;
+    }
+    ret = calendar_db_update_records(callback_data->list);
+
+    callback_data->callback(ret, callback_data->user_data);
+
+    calendar_list_destroy(callback_data->list, true);
+    CAL_FREE(callback_data);
+    return false;
+}
+
+static gboolean  __cal_db_delete_records_idle(void* user_data)
+{
+    __delete_records_data_s* callback_data = user_data;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (callback_data == NULL)
+    {
+        ERR("data is NULL");
+        return false;
+    }
+    ret = calendar_db_delete_records(callback_data->view_uri,callback_data->ids,callback_data->count);
+
+    callback_data->callback(ret, callback_data->user_data);
+
+    CAL_FREE(callback_data->ids);
+    CAL_FREE(callback_data);
+    return false;
+}
+static gboolean  __cal_db_insert_vcalendars_idle(void* user_data)
+{
+    __insert_vcalendars_data_s* callback_data = user_data;
+    int ret = CALENDAR_ERROR_NONE;
+    int *ids = NULL;
+    int count = 0;
+
+    if (callback_data == NULL)
+    {
+        ERR("data is NULL");
+        return false;
+    }
+
+    ret = calendar_db_insert_vcalendars(callback_data->vcalendar_stream, &ids, &count);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        callback_data->callback(ret, ids, count, callback_data->user_data);
+    }
+    else
+    {
+        callback_data->callback(ret, NULL, 0, callback_data->user_data);
+    }
+
+    CAL_FREE(callback_data->vcalendar_stream);
+    CAL_FREE(callback_data);
+    CAL_FREE(ids);
+    return false;
+}
+
+static gboolean  __cal_db_replace_vcalendars_idle(void* user_data)
+{
+    __replace_vcalendars_data_s* callback_data = user_data;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (callback_data == NULL)
+    {
+        ERR("data is NULL");
+        return false;
+    }
+    ret = calendar_db_replace_vcalendars(callback_data->vcalendar_stream,
+            callback_data->ids,callback_data->count);
+
+    callback_data->callback(ret, callback_data->user_data);
+
+    CAL_FREE(callback_data->vcalendar_stream);
+    CAL_FREE(callback_data->ids);
+    CAL_FREE(callback_data);
+    return false;
+}
+
+static gboolean  __cal_db_replace_records_idle(void* user_data)
+{
+    __replace_records_data_s* callback_data = user_data;
+    int ret = CALENDAR_ERROR_NONE;
+
+    if (callback_data == NULL)
+    {
+        ERR("data is NULL");
+        return false;
+    }
+    ret = calendar_db_replace_records(callback_data->list,callback_data->ids,callback_data->count);
+
+    callback_data->callback(ret, callback_data->user_data);
+
+    calendar_list_destroy(callback_data->list, true);
+    CAL_FREE(callback_data->ids);
+    CAL_FREE(callback_data);
+    return false;
+}
+
+#endif
+
+static cal_db_plugin_cb_s* __cal_db_get_plugin(cal_record_type_e type)
+{
+    switch (type)
+    {
+    case CAL_RECORD_TYPE_CALENDAR:
+        return (&_cal_db_calendar_plugin_cb);
+    case CAL_RECORD_TYPE_EVENT:
+        return (&_cal_db_event_plugin_cb);
+    case CAL_RECORD_TYPE_TODO:
+        return (&_cal_db_todo_plugin_cb);
+    case CAL_RECORD_TYPE_ALARM:
+        return (&_cal_db_alarm_plugin_cb);
+    case CAL_RECORD_TYPE_ATTENDEE:
+        return (&_cal_db_attendee_plugin_cb);
+    case CAL_RECORD_TYPE_TIMEZONE:
+        return (&_cal_db_timezone_plugin_cb);
+    case CAL_RECORD_TYPE_INSTANCE_NORMAL:
+        return (&_cal_db_instance_normal_plugin_cb);
+    case CAL_RECORD_TYPE_INSTANCE_ALLDAY:
+        return (&_cal_db_instance_allday_plugin_cb);
+    case CAL_RECORD_TYPE_SEARCH:
+        return (&_cal_db_search_plugin_cb);
+    case CAL_RECORD_TYPE_EXTENDED:
+        return (&_cal_db_extended_plugin_cb);
+    default:
+        return NULL;
+    }
+    return NULL;
+}
+
+static void __cal_db_initialize_view_table(void)
+{
+    cal_db_util_error_e dbret;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+
+    /*
+     * CAL_VIEW_TABLE_EVENT
+     * schedule_table(type=1) + rrule_table
+     */
+    snprintf(query, sizeof(query),
+                "CREATE TEMP VIEW %s AS "
+                "SELECT A.*, "
+                "B.freq, B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
+                "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
+                "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst, C.deleted "
+                "FROM %s as A "
+                "LEFT OUTER JOIN %s B ON A.id = B.event_id "
+                "JOIN %s C ON A.calendar_id = C.id "
+                "WHERE A.type = %d "
+                "AND C.deleted = 0 ",
+                CAL_VIEW_TABLE_EVENT,
+                CAL_TABLE_SCHEDULE,
+                CAL_TABLE_RRULE,
+                CAL_TABLE_CALENDAR,
+                CAL_SCH_TYPE_EVENT);
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("create view fail");
+    }
+
+    /*
+     * CAL_VIEW_TABLE_TODO
+     * schedule_table(type=2) + rrule_table
+     */
+    snprintf(query, sizeof(query),
+                "CREATE TEMP VIEW %s AS "
+                "SELECT A.*, "
+                "B.freq, B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
+                "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
+                "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst, C.deleted "
+                "FROM %s as A "
+                "LEFT OUTER JOIN %s B ON A.id = B.event_id "
+                "JOIN %s C ON A.calendar_id = C.id "
+                "WHERE A.type = %d "
+                "AND C.deleted = 0 ",
+                CAL_VIEW_TABLE_TODO,
+                CAL_TABLE_SCHEDULE,
+                CAL_TABLE_RRULE,
+                CAL_TABLE_CALENDAR,
+                CAL_SCH_TYPE_TODO);
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("create view fail");
+    }
+
+    /*
+     * CAL_VIEW_TABLE_NORMAL_INSTANCE  : CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR
+     * normal_instance_table + schedule_table(type=1) + calendar_table
+     * A = normal_instace_table
+     * B = schedule_table
+     * C = calendar_table
+     */
+    snprintf(query, sizeof(query),
+            "CREATE TEMP VIEW %s AS SELECT A.event_id, "
+            "B.dtstart_type, A.dtstart_utime, B.dtstart_datetime, "
+            "B.dtend_type, A.dtend_utime, B.dtend_datetime, "
+            "B.summary, B.description, "
+            "B.location, B.busy_status, B.task_status, B.priority, B.sensitivity, "
+            "B.rrule_id, B.latitude, B.longitude, B.has_alarm, B.original_event_id, "
+            "B.calendar_id, B.last_mod, "
+                       "C.visibility, C.account_id "
+            "FROM %s as A, %s as B, %s as C "
+            "ON A.event_id = B.id AND B.calendar_id = C.id "
+            "where C.deleted = 0",
+            CAL_VIEW_TABLE_NORMAL_INSTANCE,
+            CAL_TABLE_NORMAL_INSTANCE,
+            CAL_TABLE_SCHEDULE,
+            CAL_TABLE_CALENDAR);
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("create view fail");
+    }
+
+    // CAL_VIEW_TABLE_ALLDAY_INSTANCE  : CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR
+    snprintf(query, sizeof(query),
+            "CREATE TEMP VIEW %s AS SELECT A.event_id, "
+            "B.dtstart_type, B.dtstart_utime, A.dtstart_datetime, "
+            "B.dtend_type, B.dtend_utime, A.dtend_datetime, "
+            "B.summary, B.description, "
+            "B.location, B.busy_status, B.task_status, B.priority, B.sensitivity, "
+            "B.rrule_id, B.latitude, B.longitude, B.has_alarm, B.original_event_id, "
+            "B.calendar_id, B.last_mod, "
+            "C.visibility, C.account_id "
+            "FROM %s as A, %s as B, %s as C "
+            "ON A.event_id = B.id AND B.calendar_id = C.id "
+            "where C.deleted = 0",
+            CAL_VIEW_TABLE_ALLDAY_INSTANCE,
+            CAL_TABLE_ALLDAY_INSTANCE,
+            CAL_TABLE_SCHEDULE,
+            CAL_TABLE_CALENDAR);
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("create view fail");
+    }
+
+    // event_calendar view  :  CALENDAR_VIEW_EVENT_CALENDAR
+    snprintf(query, sizeof(query),
+                "CREATE TEMP VIEW %s AS "
+                "SELECT A.* "
+                ", B.freq, B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
+                "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
+                "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst "
+                ", C.*"
+                "FROM %s A "
+                "JOIN %s C ON A.calendar_id = C.id "
+                "LEFT OUTER JOIN %s B ON A.id = B.event_id "
+                "WHERE A.type = 1 AND c.deleted = 0",
+                CAL_VIEW_TABLE_EVENT_CALENDAR,
+                CAL_TABLE_SCHEDULE, CAL_TABLE_CALENDAR,
+                CAL_TABLE_RRULE );
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("create view fail");
+    }
+
+    // todo_calendar view  : CALENDAR_VIEW_TODO_CALENDAR
+    snprintf(query, sizeof(query),
+                "CREATE TEMP VIEW %s AS "
+                "SELECT A.* "
+                ", B.freq, B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
+                "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
+                "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst "
+                ", C.*"
+                "FROM %s A "
+                "JOIN %s C ON A.calendar_id = C.id "
+                "LEFT OUTER JOIN %s B ON A.id = B.event_id "
+                "WHERE A.type = 2 AND c.deleted = 0",
+                CAL_VIEW_TABLE_TODO_CALENDAR,
+                CAL_TABLE_SCHEDULE, CAL_TABLE_CALENDAR,
+                CAL_TABLE_RRULE);
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("create view fail");
+    }
+
+    // event_calendar_attendee view  :  CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE
+    snprintf(query, sizeof(query),
+                "CREATE TEMP VIEW %s AS "
+                "SELECT A.* "
+                ", D.freq, D.range_type, D.until_type, D.until_utime, D.until_datetime, D.count, "
+                "D.interval, D.bysecond, D.byminute, D.byhour, D.byday, D.bymonthday, "
+                "D.byyearday, D.byweekno, D.bymonth, D.bysetpos, D.wkst "
+                ", B.*, C.*"
+                "FROM %s A "
+                "LEFT OUTER  JOIN %s B ON A.id = B.event_id "
+                "JOIN %s C ON A.calendar_id = C.id "
+                "LEFT OUTER JOIN %s D ON A.id = D.event_id "
+                "WHERE A.type = 1 AND c.deleted = 0 ",
+                CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE,
+                CAL_TABLE_SCHEDULE, CAL_TABLE_ATTENDEE, CAL_TABLE_CALENDAR,
+                CAL_TABLE_RRULE );
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("create view fail");
+    }
+
+    return ;
+}
+
+int _cal_db_open(void)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    ret = _cal_db_util_open();
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        __cal_db_initialize_view_table();
+    }
+    return ret;
+}
+
+int _cal_db_close(void)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    ret = _cal_db_util_close();
+    return ret;
+}
+
+API int calendar_db_get_changes_by_version(const char* view_uri, int calendar_book_id, int calendar_db_version, calendar_list_h* record_list, int *current_calendar_db_version )
+{
+    char buf[64] = {0};
+    const char *query_cur_version = "SELECT ver FROM "CAL_TABLE_VERSION;
+    int transaction_ver = 0;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    int ret = 0;
+    int is_deleted = 0;
+
+    retvm_if(NULL == current_calendar_db_version || NULL == view_uri || NULL == record_list,
+            CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = _cal_db_util_query_get_first_int_result(query_cur_version, NULL, &transaction_ver);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+
+    if (calendar_book_id > 0)
+    {
+        snprintf(buf, sizeof(buf), "AND calendar_id = %d ", calendar_book_id);
+    }
+    else
+    {
+        memset(buf, 0x0, sizeof(buf));
+    }
+
+    if (strcmp(view_uri,_calendar_event._uri) == 0)
+    {
+        snprintf(query, sizeof(query),
+                "SELECT id, changed_ver, created_ver, is_deleted, calendar_id FROM %s "
+                "WHERE changed_ver > %d AND changed_ver <= %d AND original_event_id = %d %s"
+                "UNION "
+                "SELECT schedule_id, deleted_ver, -1, 1, calendar_id FROM %s "
+                "WHERE deleted_ver > %d AND schedule_type = %d %s"
+                ,
+                CAL_VIEW_TABLE_EVENT,
+                calendar_db_version, transaction_ver, CAL_INVALID_ID, buf,
+                CAL_TABLE_DELETED, calendar_db_version, CAL_RECORD_TYPE_EVENT, buf);
+               DBG("event qeury[%s]", query);
+    }
+    else if (strcmp(view_uri,_calendar_todo._uri) == 0)
+    {
+        snprintf(query, sizeof(query),
+                "SELECT id, changed_ver, created_ver, is_deleted, calendar_id FROM %s "
+                "WHERE changed_ver > %d AND changed_ver <= %d AND original_event_id = %d %s"
+                "UNION "
+                "SELECT schedule_id, deleted_ver, -1, 1, calendar_id FROM %s "
+                "WHERE deleted_ver > %d AND schedule_type = %d %s"
+                ,
+                CAL_VIEW_TABLE_TODO,
+                calendar_db_version, transaction_ver, CAL_INVALID_ID, buf,
+                CAL_TABLE_DELETED, calendar_db_version, CAL_RECORD_TYPE_TODO, buf);
+               DBG("todo qeury[%s]", query);
+    }
+    else
+    {
+        ERR("Invalid parameter");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    ret = calendar_list_create(record_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_list_create() Failed");
+        return ret;
+    }
+
+    stmt = _cal_db_util_query_prepare(query);
+
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*record_list, true);
+        *record_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, );
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        int id = 0, calendar_id = 0,type = 0;
+        int ver = 0;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_updated_info._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*record_list, true);
+            *record_list = NULL;
+                       sqlite3_finalize(stmt);
+            return ret;
+        }
+
+        id = sqlite3_column_int(stmt, 0);
+        ver = sqlite3_column_int(stmt, 1);
+        is_deleted = sqlite3_column_int(stmt, 3);
+        if (is_deleted == 1)
+        {
+            type = CALENDAR_RECORD_MODIFIED_STATUS_DELETED;
+        }
+        else if (sqlite3_column_int(stmt, 2) != ver)
+        {
+            type = CALENDAR_RECORD_MODIFIED_STATUS_UPDATED;
+        }
+        else
+        {
+            type = CALENDAR_RECORD_MODIFIED_STATUS_INSERTED;
+        }
+
+        calendar_id = sqlite3_column_int(stmt, 4);
+
+        _cal_record_set_int(record,_calendar_updated_info.id,id);
+        _cal_record_set_int(record,_calendar_updated_info.calendar_book_id,calendar_id);
+        _cal_record_set_int(record,_calendar_updated_info.modified_status,type);
+        _cal_record_set_int(record,_calendar_updated_info.version,ver);
+
+        ret = calendar_list_add(*record_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*record_list, true);
+            *record_list = NULL;
+            calendar_record_destroy(record, true);
+                       sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    *current_calendar_db_version = transaction_ver;
+       sqlite3_finalize(stmt);
+
+       calendar_list_first(*record_list);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_get_current_version(int* current_version)
+{
+    const char *query = "SELECT ver FROM "CAL_TABLE_VERSION;
+    int transaction_ver = 0;
+       int ret;
+
+    retvm_if(NULL == current_version, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &transaction_ver);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    if (current_version) *current_version = transaction_ver;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_insert_record( calendar_record_h record, int* id )
+{
+       cal_record_s *temp=NULL ;
+       int ret = CALENDAR_ERROR_NONE;
+
+       retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       temp = (cal_record_s*)(record);
+
+       cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+       retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == plugin_cb->insert_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+       ret = plugin_cb->insert_record(record, id);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        ret = _cal_db_util_end_trans(true);
+    }
+    else
+    {
+        _cal_db_util_end_trans(false);
+    }
+
+       return ret;
+}
+
+API int calendar_db_get_record( const char* view_uri, int id, calendar_record_h* out_record )
+{
+       int ret = CALENDAR_ERROR_NONE;
+       cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+       retvm_if(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       type = _cal_view_get_type(view_uri);
+
+       cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+       retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == plugin_cb->get_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = plugin_cb->get_record(id, out_record);
+
+       return ret;
+}
+
+API int calendar_db_update_record( calendar_record_h record )
+{
+       cal_record_s *temp=NULL ;
+       int ret = CALENDAR_ERROR_NONE;
+
+       retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       temp = (cal_record_s*)(record);
+
+       cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+       retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == plugin_cb->update_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+       ret = plugin_cb->update_record(record);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        ret = _cal_db_util_end_trans(true);
+    }
+    else
+    {
+        _cal_db_util_end_trans(false);
+    }
+
+       return ret;
+}
+
+API int calendar_db_delete_record( const char* view_uri, int id )
+{
+       int ret = CALENDAR_ERROR_NONE;
+       cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+       retvm_if(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       type = _cal_view_get_type(view_uri);
+
+       cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+       retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == plugin_cb->delete_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+       ret = plugin_cb->delete_record(id);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        ret = _cal_db_util_end_trans(true);
+    }
+    else
+    {
+        _cal_db_util_end_trans(false);
+    }
+
+       return ret;
+}
+
+API int calendar_db_get_all_records( const char* view_uri, int offset, int limit, calendar_list_h* out_list )
+{
+       int ret = CALENDAR_ERROR_NONE;
+       cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+       calendar_list_h list = NULL;
+
+       retvm_if(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       type = _cal_view_get_type(view_uri);
+
+       cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+       retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == plugin_cb->get_all_records, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = plugin_cb->get_all_records(offset,limit, &list);
+    if (CALENDAR_ERROR_NONE != ret)
+    {
+               ERR("get_all_records() failed");
+               return ret;
+       }
+       calendar_list_first(list);
+       if (out_list) *out_list = list;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list )
+{
+       int ret = CALENDAR_ERROR_NONE;
+       cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+       cal_query_s *que = NULL;
+       calendar_list_h list = NULL;
+
+       retvm_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       que = (cal_query_s *)query;
+
+       type = _cal_view_get_type(que->view_uri);
+
+       cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+       retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       retvm_if(NULL == plugin_cb->get_records_with_query, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = plugin_cb->get_records_with_query(query,offset,limit, &list);
+    if (CALENDAR_ERROR_NONE != ret)
+    {
+               ERR("get_records_with_query() failed");
+               return ret;
+       }
+       calendar_list_first(list);
+       if (out_list) *out_list = list;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_clean_after_sync( int calendar_book_id )
+{
+    int ret;
+    char query[CAL_DB_SQL_MIN_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    retvm_if(calendar_book_id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "calendar_id(%d) is Invalid", calendar_book_id);
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+    // !! please check rrule_table, alarm_table, attendee_table ..
+
+    /* delete event table */
+    snprintf(query, sizeof(query), "DELETE FROM %s "
+            "WHERE is_deleted = 1 AND calendar_id = %d",
+            CAL_TABLE_SCHEDULE,
+            calendar_book_id);
+
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("DB failed");
+        _cal_db_util_end_trans(false);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+    retvm_if(ret < 0, ret, "cals_query_exec() failed (%d)", ret);
+
+    /* delete delete table */
+    snprintf(query, sizeof(query), "DELETE FROM %s "
+            "WHERE calendar_id = %d",
+            CAL_TABLE_DELETED,
+            calendar_book_id);
+
+    dbret = _cal_db_util_query_exec(query);
+    CAL_DBG("%s",query);
+    if (dbret != CAL_DB_OK)
+    {
+        ERR("DB failed");
+        _cal_db_util_end_trans(false);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    _cal_db_util_end_trans(true);
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_get_count( const char* view_uri, int *out_count )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    retvm_if(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    type = _cal_view_get_type(view_uri);
+
+    cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+    retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == plugin_cb->get_count, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = plugin_cb->get_count(out_count);
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_get_count_with_query( calendar_query_h query, int *out_count )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+    cal_query_s *que = NULL;
+
+    retvm_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    que = (cal_query_s *)query;
+
+    type = _cal_view_get_type(que->view_uri);
+
+    cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+    retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == plugin_cb->get_count_with_query, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = plugin_cb->get_count_with_query(query, out_count);
+    return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_db_insert_records(calendar_list_h list, int** ids, int* count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       int i;
+       int *_ids = NULL;
+       int _count = 0;
+
+    retvm_if(NULL == list, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+       ret = _cal_db_util_begin_trans();
+       if ( ret != CALENDAR_ERROR_NONE)
+       {
+               ERR("Db failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       _count = 0;
+       calendar_list_get_count(list, &_count);
+       DBG("list count(%d)", _count);
+
+       _ids = calloc(_count, sizeof(int));
+
+       calendar_list_first(list);
+       for (i = 0; i < _count; i++)
+       {
+               calendar_record_h record = NULL;
+               ret = calendar_list_get_current_record_p(list, &record);
+               if (record == NULL|| ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("No record in the list");
+                       _cal_db_util_end_trans(false);
+                       CAL_FREE(_ids);
+                       return ret;
+               }
+
+               cal_record_s *temp = (cal_record_s *)record;
+               cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+               if (NULL == plugin_cb || NULL == plugin_cb->insert_record)
+               {
+                       DBG("Not plugin");
+                       _cal_db_util_end_trans(false);
+                       CAL_FREE(_ids);
+                       ret = CALENDAR_ERROR_NOT_PERMITTED;
+                       return ret;
+               }
+               ret = plugin_cb->insert_record(record, &_ids[i]);
+               if (ret != CALENDAR_ERROR_NONE)
+               {
+                       DBG("Failed to insert record");
+                       _cal_db_util_end_trans(false);
+                       CAL_FREE(_ids);
+                       return ret;
+               }
+               DBG("insert with id(%d)", _ids[i]);
+               calendar_list_next(list);
+       }
+
+       if (ids)
+       {
+               *ids = _ids;
+       }
+       else
+       {
+               CAL_FREE(_ids);
+       }
+       if (count) *count = _count;
+       _cal_db_util_end_trans(true);
+
+    return ret;
+}
+
+API int calendar_db_insert_records_async(calendar_list_h list, calendar_db_insert_result_cb callback, void *user_data)
+{
+    retvm_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef CAL_NATIVE
+    if (callback != NULL)
+    {
+        int ret = CALENDAR_ERROR_NONE;
+        calendar_list_h out_list = NULL;
+
+        ret = _cal_list_clone(list, &out_list);
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+
+        __insert_records_data_s *callback_data = NULL;
+        callback_data = calloc(1,sizeof(__insert_records_data_s));
+
+        if (callback_data == NULL)
+        {
+            ERR("calloc fail");
+            calendar_list_destroy(out_list, true);
+            return CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+        callback_data->list = out_list;
+        callback_data->callback = callback;
+        callback_data->user_data = user_data;
+        g_idle_add( &__cal_db_insert_records_idle, callback_data);
+        return CALENDAR_ERROR_NONE;
+    }
+#endif
+    int ret = CALENDAR_ERROR_NONE;
+       int i;
+    int *ids = NULL;
+       int count = 0;
+
+    retvm_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ret = _cal_db_util_begin_trans();
+       if ( ret != CALENDAR_ERROR_NONE)
+       {
+               ERR("Db failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       calendar_list_get_count(list, &count);
+       DBG("list count(%d)", count);
+
+       ids = calloc(count, sizeof(int));
+
+       calendar_list_first(list);
+       for (i = 0; i < count; i++)
+       {
+               calendar_record_h record = NULL;
+               ret = calendar_list_get_current_record_p(list, &record);
+               if (record == NULL || ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("No record in the list");
+                       CAL_FREE(ids);
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+
+               cal_record_s *temp = (cal_record_s *)record;
+               cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+               if (NULL == plugin_cb || NULL == plugin_cb->insert_record)
+               {
+                       DBG("Not plugin");
+                       CAL_FREE(ids);
+                       _cal_db_util_end_trans(false);
+                       ret = CALENDAR_ERROR_NOT_PERMITTED;
+                       return ret;
+               }
+               ret = plugin_cb->insert_record(record, &ids[i]);
+               if (ret != CALENDAR_ERROR_NONE)
+               {
+                       DBG("Failed to insert record");
+                       CAL_FREE(ids);
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+               DBG("insert with id(%d)", ids[i]);
+               calendar_list_next(list);
+       }
+       CAL_FREE(ids);
+       _cal_db_util_end_trans(true);
+
+    return ret;
+}
+
+API int calendar_db_update_records( calendar_list_h list)
+{
+       int i;
+       int count = 0;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retvm_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ret = _cal_db_util_begin_trans();
+       if ( ret != CALENDAR_ERROR_NONE)
+       {
+               ERR("Db failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       calendar_list_get_count(list, &count);
+       DBG("update list count(%d", count);
+
+       calendar_list_first(list);
+       for (i = 0; i < count; i++)
+       {
+               calendar_record_h record = NULL;
+               ret = calendar_list_get_current_record_p(list, &record);
+               if (record == NULL || ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("No record in the list");
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+
+               cal_record_s *temp = (cal_record_s *)record;
+               cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+               if (NULL == plugin_cb || NULL == plugin_cb->update_record)
+               {
+                       ERR("Not plugin");
+                       _cal_db_util_end_trans(false);
+                       ret = CALENDAR_ERROR_NOT_PERMITTED;
+                       return ret;
+               }
+               ret = plugin_cb->update_record(record);
+               if (ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("Failed to update record");
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+               DBG("update record");
+               calendar_list_next(list);
+       }
+       _cal_db_util_end_trans(true);
+
+    return ret;
+}
+
+API int calendar_db_update_records_async( calendar_list_h list, calendar_db_result_cb callback, void *user_data)
+{
+    retvm_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef CAL_NATIVE
+    if (callback != NULL)
+    {
+        int ret = CALENDAR_ERROR_NONE;
+        calendar_list_h out_list = NULL;
+        ret = _cal_list_clone(list, &out_list);
+        retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+
+        __update_records_data_s *callback_data = NULL;
+        callback_data = calloc(1,sizeof(__update_records_data_s));
+
+        if (callback_data == NULL)
+        {
+            ERR("calloc fail");
+            calendar_list_destroy(out_list, true);
+            return CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+        callback_data->list = out_list;
+        callback_data->callback = callback;
+        callback_data->user_data = user_data;
+        g_idle_add( &__cal_db_update_records_idle, callback_data);
+        return CALENDAR_ERROR_NONE;
+    }
+#endif
+       int i;
+       int count = 0;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retvm_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ret = _cal_db_util_begin_trans();
+       if (ret != CALENDAR_ERROR_NONE)
+       {
+               ERR("Db failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       calendar_list_get_count(list, &count);
+       DBG("update list count(%d", count);
+
+       calendar_list_first(list);
+       for (i = 0; i < count; i++)
+       {
+               calendar_record_h record = NULL;
+               ret = calendar_list_get_current_record_p(list, &record);
+               if (record == NULL || ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("No record in the list");
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+
+               cal_record_s *temp = (cal_record_s *)record;
+               cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+               if (NULL == plugin_cb || NULL == plugin_cb->insert_record)
+               {
+                       ERR("Not plugin");
+                       _cal_db_util_end_trans(false);
+                       ret = CALENDAR_ERROR_NOT_PERMITTED;
+                       return ret;
+               }
+               ret = plugin_cb->update_record(record);
+               if (ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("Failed to update record");
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+               DBG("update record");
+               calendar_list_next(list);
+       }
+       _cal_db_util_end_trans(true);
+
+    return ret;
+}
+
+API int calendar_db_delete_records(const char* view_uri, int record_id_array[], int count)
+{
+    retvm_if(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    int ret = CALENDAR_ERROR_NONE;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    type = _cal_view_get_type(view_uri);
+
+    cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+    retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == plugin_cb->delete_records, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+    ret = plugin_cb->delete_records(record_id_array,count);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        ret = _cal_db_util_end_trans(true);
+    }
+    else
+    {
+        _cal_db_util_end_trans(false);
+    }
+    return ret;
+}
+
+API int calendar_db_delete_records_async(const char* view_uri, int ids[], int count, calendar_db_result_cb callback, void *user_data)
+{
+    retvm_if(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == ids, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+#ifdef CAL_NATIVE
+    if (callback != NULL)
+    {
+        __delete_records_data_s *callback_data = NULL;
+        callback_data = calloc(1,sizeof(__delete_records_data_s));
+
+        if (callback_data == NULL)
+        {
+            ERR("calloc fail");
+            return CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+        callback_data->view_uri = view_uri;
+        callback_data->ids = calloc(1, sizeof(int)*count);
+        if (callback_data->ids == NULL)
+        {
+            CAL_FREE(callback_data);
+            ERR("calloc fail");
+            return CALENDAR_ERROR_OUT_OF_MEMORY;
+        }
+        memcpy(callback_data->ids, ids, sizeof(int)*count);
+        callback_data->count = count;
+        callback_data->callback = callback;
+        callback_data->user_data = user_data;
+        g_idle_add( &__cal_db_delete_records_idle, callback_data);
+        return CALENDAR_ERROR_NONE;
+    }
+#endif
+    int ret = CALENDAR_ERROR_NONE;
+    cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
+
+    type = _cal_view_get_type(view_uri);
+
+    cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(type);
+    retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == plugin_cb->delete_records, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+    ret = plugin_cb->delete_records(ids,count);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        ret = _cal_db_util_end_trans(true);
+    }
+    else
+    {
+        _cal_db_util_end_trans(false);
+    }
+    return ret;
+}
+
+API int calendar_db_insert_vcalendars(const char* vcalendar_stream, int **record_id_array, int *count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_list_h list = NULL;
+    int list_count = 0;
+    int i = 0;
+    int *ids = NULL;
+
+    retvm_if(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_vcalendar_parse_to_calendar(vcalendar_stream, &list);
+    retvm_if(ret != CALENDAR_ERROR_NONE, ret, "parse fail");
+
+    ret = calendar_list_get_count(list, &list_count);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        calendar_list_destroy(list, true);
+        ERR("get count fail");
+        return ret;
+    }
+
+    calendar_list_first(list);
+    ids = calloc(1, sizeof(int)*list_count);
+    if (ids == NULL)
+    {
+        calendar_list_destroy(list, true);
+        ERR("calloc fail");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+
+    ret = _cal_db_util_begin_trans();
+
+    if ( ret != CALENDAR_ERROR_NONE)
+    {
+        calendar_list_destroy(list, true);
+        CAL_FREE(ids);
+        ERR("Db failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    for(i=0;i<list_count;i++)
+    {
+        calendar_record_h record = NULL;
+
+        ret = calendar_list_get_current_record_p(list, &record);
+        if( ret != CALENDAR_ERROR_NONE)
+        {
+            calendar_list_destroy(list, true);
+            CAL_FREE(ids);
+            ERR("list get fail");
+            _cal_db_util_end_trans(false);
+            return ret;
+        }
+
+        // insert
+        ret = calendar_db_insert_record(record, &ids[i]);
+        if( ret != CALENDAR_ERROR_NONE)
+        {
+            calendar_list_destroy(list, true);
+            CAL_FREE(ids);
+            ERR("list get fail");
+            _cal_db_util_end_trans(false);
+            return ret;
+        }
+
+        calendar_list_next(list);
+    }
+
+    _cal_db_util_end_trans(true);
+
+    *record_id_array = ids;
+    *count = list_count;
+
+    calendar_list_destroy(list, true);
+    return ret;
+}
+
+API int calendar_db_insert_vcalendars_async(const char* vcalendar_stream, calendar_db_insert_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    retvm_if(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == callback, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef CAL_NATIVE
+
+    __insert_vcalendars_data_s *callback_data = NULL;
+    callback_data = calloc(1,sizeof(__insert_vcalendars_data_s));
+
+    if (callback_data == NULL)
+    {
+        ERR("calloc fail");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    callback_data->vcalendar_stream = SAFE_STRDUP(vcalendar_stream);
+    callback_data->callback = callback;
+    callback_data->user_data = user_data;
+    g_idle_add( &__cal_db_insert_vcalendars_idle, callback_data);
+
+#endif
+    return ret;
+}
+
+API int calendar_db_replace_vcalendars(const char* vcalendar_stream, int *record_id_array, int count)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_list_h list = NULL;
+    int list_count = 0;
+    int i = 0;
+
+    retvm_if(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_vcalendar_parse_to_calendar(vcalendar_stream, &list);
+    retvm_if(ret != CALENDAR_ERROR_NONE, ret, "parse fail");
+
+    ret = calendar_list_get_count(list, &list_count);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        calendar_list_destroy(list, true);
+        ERR("get count fail");
+        return ret;
+    }
+
+    // check count
+    if (count != list_count)
+    {
+        calendar_list_destroy(list, true);
+        ERR("get count fail vcalendar_count=%d, input count=%d", list_count, count);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    calendar_list_first(list);
+
+    ret = _cal_db_util_begin_trans();
+
+    if ( ret != CALENDAR_ERROR_NONE)
+    {
+        calendar_list_destroy(list, true);
+        ERR("Db failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    for(i=0;i<list_count;i++)
+    {
+        calendar_record_h record = NULL;
+        char *view_uri = NULL;
+
+        ret = calendar_list_get_current_record_p(list, &record);
+        if( ret != CALENDAR_ERROR_NONE)
+        {
+            calendar_list_destroy(list, true);
+            ERR("list get fail");
+            _cal_db_util_end_trans(false);
+            return ret;
+        }
+
+        // set_id
+        ret = calendar_record_get_uri_p(record, &view_uri);
+        if( ret != CALENDAR_ERROR_NONE)
+        {
+            calendar_list_destroy(list, true);
+            ERR("record get uri fail");
+            _cal_db_util_end_trans(false);
+            return ret;
+        }
+
+        if(strcmp(view_uri, _calendar_event._uri) == 0)
+        {
+            ret = _cal_record_set_int(record, _calendar_event.id, record_id_array[i]);
+        }
+        else if(strcmp(view_uri, _calendar_todo._uri) == 0)
+        {
+            ret = _cal_record_set_int(record, _calendar_todo.id, record_id_array[i]);
+        }
+        else
+        {
+            calendar_list_destroy(list, true);
+            ERR("record get uri(%s) fail", view_uri);
+            _cal_db_util_end_trans(false);
+            return ret;
+        }
+
+        if( ret != CALENDAR_ERROR_NONE)
+        {
+            calendar_list_destroy(list, true);
+            ERR("record set fail");
+            _cal_db_util_end_trans(false);
+            return ret;
+        }
+
+        // update
+        ret = calendar_db_update_record(record);
+        if( ret != CALENDAR_ERROR_NONE)
+        {
+            calendar_list_destroy(list, true);
+            ERR("list get fail");
+            _cal_db_util_end_trans(false);
+            return ret;
+        }
+
+        calendar_list_next(list);
+    }
+
+    _cal_db_util_end_trans(true);
+
+    calendar_list_destroy(list, true);
+
+    return ret;
+}
+
+API int calendar_db_replace_vcalendars_async(const char* vcalendar_stream, int *record_id_array, int count, calendar_db_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    retvm_if(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == callback, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef CAL_NATIVE
+
+    __replace_vcalendars_data_s *callback_data = NULL;
+    callback_data = calloc(1,sizeof(__replace_vcalendars_data_s));
+
+    if (callback_data == NULL)
+    {
+        ERR("calloc fail");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    callback_data->ids = calloc(1, sizeof(int)*count);
+    if (callback_data->ids == NULL)
+    {
+        CAL_FREE(callback_data);
+        ERR("calloc fail");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    memcpy(callback_data->ids, record_id_array, sizeof(int)*count);
+    callback_data->vcalendar_stream = SAFE_STRDUP(vcalendar_stream);
+    callback_data->callback = callback;
+    callback_data->user_data = user_data;
+    callback_data->count = count;
+    g_idle_add( &__cal_db_replace_vcalendars_idle, callback_data);
+
+#endif
+    return ret;
+}
+
+API int calendar_db_replace_record(calendar_record_h record, int record_id)
+{
+    cal_record_s *temp=NULL ;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retvm_if(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(record_id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    temp = (cal_record_s*)(record);
+
+    cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+    retvm_if(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == plugin_cb->replace_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+    ret = plugin_cb->replace_record(record, record_id);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        ret = _cal_db_util_end_trans(true);
+    }
+    else
+    {
+        _cal_db_util_end_trans(false);
+    }
+
+    return ret;
+}
+
+API int calendar_db_replace_records(calendar_list_h list, int *ids, int count)
+{
+       int i;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retvm_if(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == ids, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+       ret = _cal_db_util_begin_trans();
+       if ( ret != CALENDAR_ERROR_NONE)
+       {
+               ERR("Db failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       calendar_list_first(list);
+       for (i = 0; i < count; i++)
+       {
+               calendar_record_h record = NULL;
+               ret = calendar_list_get_current_record_p(list, &record);
+               if (record == NULL || ret != CALENDAR_ERROR_NONE)
+               {
+                       ERR("No record in the list");
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+
+               cal_record_s *temp = (cal_record_s *)record;
+               cal_db_plugin_cb_s* plugin_cb = __cal_db_get_plugin(temp->type);
+               if (NULL == plugin_cb || NULL == plugin_cb->insert_record)
+               {
+                       DBG("Not plugin");
+                       _cal_db_util_end_trans(false);
+                       ret = CALENDAR_ERROR_NOT_PERMITTED;
+                       return ret;
+               }
+               ret = plugin_cb->replace_record(record, ids[i]);
+               if (ret != CALENDAR_ERROR_NONE)
+               {
+                       DBG("Failed to insert record");
+                       _cal_db_util_end_trans(false);
+                       return ret;
+               }
+               DBG("insert with id(%d)", ids[i]);
+               calendar_list_next(list);
+       }
+       _cal_db_util_end_trans(true);
+
+    return ret;
+}
+
+API int calendar_db_replace_records_async(calendar_list_h record_list, int *record_id_array, int count, calendar_db_result_cb callback, void *user_data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    retvm_if(NULL == record_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == callback, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    retvm_if(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+#ifdef CAL_NATIVE
+
+    calendar_list_h out_list = NULL;
+
+    ret = _cal_list_clone(record_list, &out_list);
+    retv_if(ret!=CALENDAR_ERROR_NONE,ret);
+
+    __replace_records_data_s *callback_data = NULL;
+    callback_data = calloc(1,sizeof(__replace_records_data_s));
+    if (callback_data == NULL)
+    {
+        ERR("calloc fail");
+               calendar_list_destroy(out_list, true);
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+
+    callback_data->ids = calloc(1, sizeof(int)*count);
+    if (callback_data->ids == NULL)
+    {
+        CAL_FREE(callback_data);
+        ERR("calloc fail");
+               calendar_list_destroy(out_list, true);
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+    memcpy(callback_data->ids, record_id_array, sizeof(int)*count);
+    callback_data->list = out_list;
+    callback_data->callback = callback;
+    callback_data->user_data = user_data;
+    callback_data->count = count;
+    g_idle_add( &__cal_db_replace_records_idle, callback_data);
+
+#endif
+    return ret;
+}
+
+API int calendar_db_get_last_change_version(int* last_version)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    retvm_if(NULL == last_version, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+    *last_version = _cal_db_util_get_transaction_ver();
+    return ret;
+}
diff --git a/native/cal_db.h b/native/cal_db.h
new file mode 100644 (file)
index 0000000..04b8000
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_H__
+#define __CALENDAR_SVC_DB_H__
+
+#include "calendar_view.h"
+#include "calendar_list.h"
+
+#define CAL_DB_PATH "/opt/usr/dbspace/.calendar-svc.db"
+#define CAL_DB_JOURNAL_PATH "/opt/usr/dbspace/.calendar-svc.db-journal"
+
+// For Security
+#define CAL_SECURITY_FILE_GROUP 6003
+#define CAL_SECURITY_DEFAULT_PERMISSION 0660
+#define CAL_SECURITY_DIR_DEFAULT_PERMISSION 0770
+
+#define CAL_DB_SQL_MAX_LEN 2048
+#define CAL_DB_SQL_MIN_LEN 1024
+
+// DB table
+#define CAL_TABLE_SCHEDULE "schedule_table"
+#define CAL_TABLE_ALARM "alarm_table"
+#define CAL_REMINDER_ALERT "reminder_table"
+#define CAL_TABLE_CALENDAR "calendar_table"
+#define CAL_TABLE_ATTENDEE "attendee_table"
+#define CAL_TABLE_TIMEZONE "timezone_table"
+#define CAL_TABLE_VERSION "version_table"
+#define CAL_TABLE_DELETED "deleted_table"
+#define CAL_TABLE_RRULE "rrule_table"
+#define CAL_TABLE_NORMAL_INSTANCE "normal_instance_table"
+#define CAL_TABLE_ALLDAY_INSTANCE "allday_instance_table"
+#define CAL_TABLE_EXTENDED "extended_table"
+
+// for event or todo..
+#define CAL_VIEW_TABLE_EVENT "event_view"
+#define CAL_VIEW_TABLE_TODO "todo_view"
+// search ?
+#define CAL_VIEW_TABLE_EVENT_CALENDAR "event_calendar_view"
+#define CAL_VIEW_TABLE_TODO_CALENDAR "todo_calendar_view"
+#define CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE "event_calendar_attendee_view"
+#define CAL_VIEW_TABLE_NORMAL_INSTANCE "normal_instance_view"
+#define CAL_VIEW_TABLE_ALLDAY_INSTANCE "allday_instance_view"
+
+typedef int (*cal_db_insert_record_cb)( calendar_record_h record, int* id );
+typedef int (*cal_db_get_record_cb)( int id, calendar_record_h* out_record );
+typedef int (*cal_db_update_record_cb)( calendar_record_h record );
+typedef int (*cal_db_delete_record_cb)( int id );
+typedef int (*cal_db_get_all_records_cb)( int offset, int limit, calendar_list_h* out_list );
+typedef int (*cal_db_get_records_with_query_cb)( calendar_query_h query, int offset, int limit, calendar_list_h* out_list );
+typedef int (*cal_db_insert_records_cb)(const calendar_list_h in_list, int** ids);
+typedef int (*cal_db_update_records_cb)(const calendar_list_h in_list);
+typedef int (*cal_db_delete_records_cb)(int ids[], int count);
+typedef int (*cal_db_get_count_cb)( int *out_count );
+typedef int (*cal_db_get_count_with_query_cb)( calendar_query_h query, int *out_count );
+typedef int (*cal_db_replace_record)(calendar_record_h record, int record_id);
+typedef int (*cal_db_replace_records)(calendar_list_h record_list, int *record_id_array, int count);
+
+typedef struct {
+    bool is_query_only;
+    cal_db_insert_record_cb insert_record;
+    cal_db_get_record_cb get_record;
+    cal_db_update_record_cb update_record;
+    cal_db_delete_record_cb delete_record;
+    cal_db_get_all_records_cb get_all_records;
+    cal_db_get_records_with_query_cb get_records_with_query;
+    cal_db_insert_records_cb insert_records;
+    cal_db_update_records_cb update_records;
+    cal_db_delete_records_cb delete_records;
+    cal_db_get_count_cb get_count;
+    cal_db_get_count_with_query_cb get_count_with_query;
+    cal_db_replace_record replace_record;
+    cal_db_replace_records replace_records;
+} cal_db_plugin_cb_s;
+
+int _cal_db_open(void);
+int _cal_db_close(void);
+
+#endif // __CALENDAR_SVC_DB_H__
diff --git a/native/cal_db_alarm.c b/native/cal_db_alarm.c
new file mode 100644 (file)
index 0000000..2866fe1
--- /dev/null
@@ -0,0 +1,1041 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <appsvc.h>
+#ifdef CAL_NATIVE
+#include <alarm.h>
+#endif
+
+#include "calendar_db.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_time.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+#include "cal_db_instance.h"
+#include "cal_db_alarm.h"
+
+#define ONE_DAY_SECONDS 86400L // seconds in a day
+#define ONE_WEEK_SECONDS 604800L // seconds in a week
+#define ONE_MONTH_SECONDS 2678400L // seconds in a month
+#define ONE_YEAR_SECONDS 31536000L // seconds in a year
+
+static int __cal_db_alarm_insert_record(calendar_record_h record, int* id);
+static int __cal_db_alarm_get_record(int id, calendar_record_h* out_record);
+static int __cal_db_alarm_update_record(calendar_record_h record);
+static int __cal_db_alarm_delete_record(int id);
+static int __cal_db_alarm_get_all_records(int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_alarm_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_alarm_insert_records(const calendar_list_h list, int** ids);
+static int __cal_db_alarm_update_records(const calendar_list_h list);
+static int __cal_db_alarm_delete_records(int ids[], int count);
+static int __cal_db_alarm_get_count(int *out_count);
+static int __cal_db_alarm_get_count_with_query(calendar_query_h query, int *out_count);
+
+/*
+ * static function
+ */
+static void __cal_db_alarm_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static void __cal_db_alarm_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record);
+static void __cal_db_alarm_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+
+
+cal_db_plugin_cb_s _cal_db_alarm_plugin_cb = {
+       .is_query_only = false,
+       .insert_record=__cal_db_alarm_insert_record,
+       .get_record=__cal_db_alarm_get_record,
+       .update_record=__cal_db_alarm_update_record,
+       .delete_record=__cal_db_alarm_delete_record,
+       .get_all_records=__cal_db_alarm_get_all_records,
+       .get_records_with_query=__cal_db_alarm_get_records_with_query,
+       .insert_records=__cal_db_alarm_insert_records,
+       .update_records=__cal_db_alarm_update_records,
+       .delete_records=__cal_db_alarm_delete_records,
+       .get_count=__cal_db_alarm_get_count,
+       .get_count_with_query=__cal_db_alarm_get_count_with_query,
+       .replace_record=NULL,
+       .replace_records=NULL
+};
+
+static int __cal_db_alarm_insert_record(calendar_record_h record, int* id)
+{
+       int record_type = CALENDAR_BOOK_TYPE_EVENT;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+       cal_alarm_s *alarm = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       alarm = (cal_alarm_s *)(record);
+       retvm_if(NULL == alarm, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: cal_alarm_s is NULL");
+
+       if (alarm->remind_tick_unit == CALENDAR_ALARM_NONE)
+       {
+               DBG("No alarm unit tick");
+               return CALENDAR_ERROR_NONE;
+       }
+       else if (alarm->remind_tick_unit != CALENDAR_ALARM_TIME_UNIT_SPECIFIC)
+       {
+               cal_db_util_error_e dbret = CAL_DB_OK;
+               char query[CAL_DB_SQL_MAX_LEN] = {0};
+               sqlite3_stmt *stmt = NULL;
+               int index;
+               int alarm_type = 0;
+               int alarm_datetime = 0;
+               long long int alarm_utime = 0;
+
+               snprintf(query, sizeof(query), "SELECT type FROM %s WHERE id = %d ",
+                               CAL_TABLE_SCHEDULE, alarm->event_id);
+               DBG("query[%s]", query);
+               stmt = _cal_db_util_query_prepare(query);
+               if (NULL == stmt)
+               {
+                       ERR("_cal_db_util_query_prepare() failed");
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+               dbret = _cal_db_util_stmt_step(stmt);
+               if (CAL_DB_ROW != dbret)
+               {
+                       ERR("_cal_db_util_stmt_step() failed");
+                       sqlite3_finalize(stmt);
+                       switch (dbret)
+                       {
+                       case CAL_DB_DONE:
+                               ERR("Failed to find record(id:%d, ret:%d)", id, dbret);
+                               return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+
+               index = 0;
+               record_type = sqlite3_column_int(stmt, index++);
+               sqlite3_finalize(stmt);
+               stmt = NULL;
+
+               switch (record_type)
+               {
+               case CALENDAR_BOOK_TYPE_EVENT:
+                       snprintf(query, sizeof(query),
+                                       "SELECT dtstart_tzid, dtstart_type, dtstart_utime, dtstart_datetime "
+                                       "FROM %s WHERE id = %d",
+                                       CAL_TABLE_SCHEDULE, alarm->event_id);
+
+                       stmt = _cal_db_util_query_prepare(query);
+                       if (NULL == stmt)
+                       {
+                               ERR("_cal_db_util_query_prepare() failed");
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+                       dbret = _cal_db_util_stmt_step(stmt);
+                       if (CAL_DB_ROW != dbret)
+                       {
+                               ERR("_cal_db_util_stmt_step() failed");
+                               sqlite3_finalize(stmt);
+                               switch (dbret)
+                               {
+                               case CAL_DB_DONE:
+                                       ERR("Failed to find record(id:%d, ret:%d)", id, dbret);
+                                       return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
+                               case CAL_DB_ERROR_NO_SPACE:
+                                       return CALENDAR_ERROR_FILE_NO_SPACE;
+                               default:
+                                       return CALENDAR_ERROR_DB_FAILED;
+                               }
+                       }
+
+                       index = 0;
+                       sqlite3_column_text(stmt, index++);
+                       alarm_type = sqlite3_column_int(stmt, index++);
+                       alarm_utime = sqlite3_column_int64(stmt, index++);
+                       alarm_datetime = sqlite3_column_int(stmt, index++);
+                       sqlite3_finalize(stmt);
+                       stmt = NULL;
+                       break;
+
+               case CALENDAR_BOOK_TYPE_TODO:
+                       snprintf(query, sizeof(query),
+                                       "SELECT dtend_tzid, dtend_type, dtend_utime, dtend_datetime "
+                                       " FROM %s WHERE id = %d",
+                                       CAL_TABLE_SCHEDULE, alarm->event_id);
+
+                       stmt = _cal_db_util_query_prepare(query);
+                       if (NULL == stmt)
+                       {
+                               ERR("_cal_db_util_query_prepare() failed");
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+                       dbret = _cal_db_util_stmt_step(stmt);
+                       if (CAL_DB_ROW != dbret)
+                       {
+                               ERR("_cal_db_util_stmt_step() failed");
+                               sqlite3_finalize(stmt);
+                               switch (dbret)
+                               {
+                               case CAL_DB_DONE:
+                                       ERR("Failed to find record(id:%d, ret:%d)", id, dbret);
+                                       return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
+                               case CAL_DB_ERROR_NO_SPACE:
+                                       return CALENDAR_ERROR_FILE_NO_SPACE;
+                               default:
+                                       return CALENDAR_ERROR_DB_FAILED;
+                               }
+                       }
+
+                       index = 0;
+                       sqlite3_column_text(stmt, index++);
+                       alarm_type = sqlite3_column_int(stmt, index++);
+                       alarm_utime = sqlite3_column_int64(stmt, index++);
+                       alarm_datetime = sqlite3_column_int(stmt, index++);
+                       sqlite3_finalize(stmt);
+                       stmt = NULL;
+                       break;
+               }
+
+               switch (alarm_type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       alarm->alarm_time = alarm_utime;
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       alarm->alarm_time = alarm_datetime;
+                       break;
+               }
+       }
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s ("
+                       "event_id, "
+                       "alarm_time, remind_tick, remind_tick_unit, "
+                       "alarm_tone, alarm_description, "
+                       "alarm_type, alarm_id "
+                       ") VALUES ( "
+                       "%d, "
+                       "%lld, %d, %d, "
+                       "?, ?, "
+                       "%d, %d )",
+                       CAL_TABLE_ALARM,
+                       alarm->event_id,
+                       alarm->alarm_time, alarm->remind_tick, alarm->remind_tick_unit,
+                       alarm->alarm_type, alarm->alarm_id);
+
+       CAL_DBG("%s",query);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       if (alarm->alarm_tone)
+               _cal_db_util_stmt_bind_text(stmt, 1, alarm->alarm_tone);
+
+       if (alarm->alarm_description)
+               _cal_db_util_stmt_bind_text(stmt, 2, alarm->alarm_description);
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_get_record(int id, calendar_record_h* out_record )
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       sqlite3_stmt *stmt = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       int ret = CALENDAR_ERROR_NONE;
+
+       retvm_if(id < 0, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: id(%d)", id);
+
+       ret = calendar_record_create(_calendar_alarm._uri, out_record);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_record_create(%d)", ret);
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+       snprintf(query, sizeof(query),
+                       "SELECT * FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ALARM,
+                       id);
+       stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_record_destroy(*out_record, true);
+        *out_record = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (dbret != CAL_DB_ROW)
+       {
+               ERR(" _cal_db_util_stmt_step() Failed(%d)", dbret);
+               sqlite3_finalize(stmt);
+               calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+        __cal_db_alarm_get_stmt(stmt,*out_record);
+       sqlite3_finalize(stmt);
+       stmt = NULL;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_update_record(calendar_record_h record )
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       cal_alarm_s *alarm = NULL;
+       sqlite3_stmt *stmt = NULL;
+
+       alarm = (cal_alarm_s *)(record);
+       retvm_if(NULL == alarm, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: record is NULL");
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET "
+                       "alarm_time = %lld, "
+                       "remind_tick = %d, "
+                       "remind_tick_unit = %d, "
+                       "alarm_tone = ?, "
+                       "alarm_description = ?, "
+                       "alarm_type = %d, "
+                       "alarm_id = %d "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ALARM,
+                       alarm->alarm_time,
+                       alarm->remind_tick,
+                       alarm->remind_tick_unit,
+                       alarm->alarm_type,
+                       alarm->alarm_id,
+                       alarm->event_id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED,
+                       "_cal_db_util_query_prepare() Failed");
+
+       if (alarm->alarm_tone)
+       {
+               _cal_db_util_stmt_bind_text(stmt, 1, alarm->alarm_tone);
+       }
+       if (alarm->alarm_description)
+       {
+               _cal_db_util_stmt_bind_text(stmt, 2, alarm->alarm_description);
+       }
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_delete_record(int id)
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+
+       snprintf(query, sizeof(query),
+                       "DELETE FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ALARM,
+                       id);
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_get_all_records(int offset, int limit, calendar_list_h* out_list )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query), "SELECT * FROM %s %s %s", CAL_TABLE_ALARM,limitquery,offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+        *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record = NULL;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_alarm._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_alarm_get_stmt(stmt,record);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list )
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+    char *table_name;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_ALARM))
+    {
+        table_name = SAFE_STRDUP(CAL_TABLE_ALARM);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", table_name);
+    }
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_alarm._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_alarm_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_alarm_get_stmt(stmt,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_insert_records(const calendar_list_h list, int** ids)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_alarm_insert_record(record, NULL) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_update_records(const calendar_list_h list)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_alarm_update_record(record) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_delete_records(int ids[], int count)
+{
+    int i=0;
+    for(i=0;i<count;i++)
+    {
+        if (__cal_db_alarm_delete_record(ids[i]) != CALENDAR_ERROR_NONE)
+        {
+            ERR("delete failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_ALARM);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_alarm_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_ALARM))
+    {
+        table_name = SAFE_STRDUP(CAL_TABLE_ALARM);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+////////////////////////////////////////////////////////////////////////////
+static void __cal_db_alarm_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
+{
+    cal_alarm_s *alarm = NULL;
+    int index;
+    const unsigned char *temp;
+
+    alarm = (cal_alarm_s*)(record);
+
+    index = 0;
+    alarm->event_id = sqlite3_column_int(stmt, index++);
+    alarm->alarm_time = sqlite3_column_int64(stmt, index++);
+    alarm->remind_tick = sqlite3_column_int(stmt, index++);
+    alarm->remind_tick_unit = sqlite3_column_int(stmt, index++);
+
+    temp = sqlite3_column_text(stmt, index++);
+    alarm->alarm_tone = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, index++);
+    alarm->alarm_description = SAFE_STRDUP(temp);
+
+    alarm->alarm_type = sqlite3_column_int(stmt, index++);
+    alarm->alarm_id = sqlite3_column_int(stmt, index++);
+
+}
+
+static void __cal_db_alarm_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record)
+{
+    cal_alarm_s *alarm = NULL;
+    const unsigned char *temp;
+
+    alarm = (cal_alarm_s*)(record);
+
+    switch(property)
+    {
+    case CAL_PROPERTY_ALARM_TYPE:
+        alarm->alarm_type = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ALARM_TIME:
+        alarm->alarm_time = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ALARM_TICK:
+        alarm->remind_tick = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ALARM_TICK_UNIT:
+        alarm->remind_tick_unit = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ALARM_TONE:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        alarm->alarm_tone = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ALARM_DESCRIPTION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        alarm->alarm_description = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ALARM_ID:
+        alarm->alarm_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ALARM_EVENT_TODO_ID:
+        alarm->event_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    default:
+        sqlite3_column_int(stmt, *stmt_count);
+        break;
+    }
+
+    *stmt_count = *stmt_count+1;
+}
+
+static void __cal_db_alarm_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_alarm_get_property_stmt(stmt,projection[i],&stmt_count,record);
+    }
+}
+
+int _cal_db_alarm_get_records(int event_id, GList **out_list)
+{
+       int ret;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+       GList *list = NULL;
+
+       retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter: GList_h is NULL");
+
+       snprintf(query, sizeof(query),
+                       "SELECT * FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ALARM,
+                       event_id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       int index = 0;
+       const unsigned char *temp;
+       calendar_record_h record = NULL;
+       cal_alarm_s *alarm = NULL;
+
+       while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+       {
+               ret = calendar_record_create(_calendar_alarm._uri, &record);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       sqlite3_finalize(stmt);
+                       return ret;
+               }
+
+               index = 0;
+               alarm = (cal_alarm_s *)(record);
+
+               alarm->event_id = sqlite3_column_int(stmt, index++);
+               alarm->alarm_time = sqlite3_column_int64(stmt, index++);
+               alarm->remind_tick = sqlite3_column_int(stmt, index++);
+               alarm->remind_tick_unit = sqlite3_column_int(stmt, index++);
+
+               temp = sqlite3_column_text(stmt, index++);
+               alarm->alarm_tone = SAFE_STRDUP(temp);
+
+               temp = sqlite3_column_text(stmt, index++);
+               alarm->alarm_description = SAFE_STRDUP(temp);
+
+               alarm->alarm_type = sqlite3_column_int(stmt, index++);
+               alarm->alarm_id = sqlite3_column_int(stmt, index++);
+
+               list = g_list_append(list, record);
+       }
+
+       *out_list = list;
+       sqlite3_finalize(stmt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_alarm_convert_gtoh(GList *glist, int id, calendar_list_h *hlist)
+{
+       int ret;
+       GList *g = NULL;
+       calendar_list_h h = NULL;
+       calendar_record_h alarm = NULL;
+
+       if (glist == NULL)
+       {
+               DBG("No alarm");
+               return CALENDAR_ERROR_NO_DATA;
+       }
+       ret = calendar_list_create(&h);
+
+       g = g_list_first(glist);
+       while (g)
+       {
+               alarm = (calendar_record_h)g->data;
+               if (alarm)
+               {
+                   CAL_DBG("%d",id);
+                   _cal_record_set_int(alarm,_calendar_alarm.event_id,id);
+                       ret = calendar_list_add(h, alarm);
+               }
+               g = g_list_next(g);
+       }
+
+       *hlist = h;
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_alarm_delete_with_id(int event_id)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    snprintf(query, sizeof(query), "DELETE FROM %s WHERE event_id=%d ",
+            CAL_TABLE_ALARM, event_id);
+
+    dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+        ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_alarm_has_alarm(GList *list)
+{
+    calendar_record_h alarm = NULL;
+    int unit = CALENDAR_ALARM_NONE;
+    GList *g = NULL;
+    int has_alarm = 0;
+
+    if (list)
+    {
+        g = g_list_first(list);
+
+        while (g)
+        {
+            alarm = (calendar_record_h)g->data;
+            calendar_record_get_int(alarm, _calendar_alarm.tick_unit, &unit);
+            if (CALENDAR_ALARM_NONE != unit)
+            {
+                has_alarm = 1;
+            }
+            g = g_list_next(g);
+        }
+
+    }
+
+    return has_alarm;
+}
diff --git a/native/cal_db_alarm.h b/native/cal_db_alarm.h
new file mode 100644 (file)
index 0000000..950853d
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_ALARM_H__
+#define __CALENDAR_SVC_DB_ALARM_H__
+
+int _cal_db_alarm_get_records(int event_id, GList **out_list);
+int _cal_db_alarm_convert_gtoh(GList *glist, int id, calendar_list_h *hlist);
+int _cal_db_alarm_delete_with_id(int event_id);
+/*
+ * @param[in] list   The alarm list
+ *
+ * @return 0 on none alarm, 1 on alarm.
+ */
+int _cal_db_alarm_has_alarm(GList *list);
+
+#endif  //__CALENDAR_SVC_DB_ALARM_H__
diff --git a/native/cal_db_attendee.c b/native/cal_db_attendee.c
new file mode 100644 (file)
index 0000000..cd6b3de
--- /dev/null
@@ -0,0 +1,962 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db_query.h"
+#include "cal_db_attendee.h"
+
+static int __cal_db_attendee_insert_record(calendar_record_h record, int* id);
+static int __cal_db_attendee_get_record(int id, calendar_record_h* out_record);
+static int __cal_db_attendee_update_record(calendar_record_h record);
+static int __cal_db_attendee_delete_record(int id);
+static int __cal_db_attendee_get_all_records(int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_attendee_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_attendee_insert_records(const calendar_list_h list, int** ids);
+static int __cal_db_attendee_update_records(const calendar_list_h list);
+static int __cal_db_attendee_delete_records(int ids[], int count);
+static int __cal_db_attendee_get_count(int *out_count);
+static int __cal_db_attendee_get_count_with_query(calendar_query_h query, int *out_count);
+/*
+ * static function
+ */
+static void __cal_db_attendee_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static void __cal_db_attendee_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record);
+static void __cal_db_attendee_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+
+cal_db_plugin_cb_s _cal_db_attendee_plugin_cb = {
+       .is_query_only = false,
+       .insert_record=__cal_db_attendee_insert_record,
+       .get_record=__cal_db_attendee_get_record,
+       .update_record=__cal_db_attendee_update_record,
+       .delete_record=__cal_db_attendee_delete_record,
+       .get_all_records=__cal_db_attendee_get_all_records,
+       .get_records_with_query=__cal_db_attendee_get_records_with_query,
+       .insert_records=__cal_db_attendee_insert_records,
+       .update_records=__cal_db_attendee_update_records,
+       .delete_records=__cal_db_attendee_delete_records,
+    .get_count=__cal_db_attendee_get_count,
+    .get_count_with_query=__cal_db_attendee_get_count_with_query,
+    .replace_record=NULL,
+    .replace_records=NULL
+};
+
+static int __cal_db_attendee_insert_record(calendar_record_h record, int* id)
+{
+       int index;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+       cal_attendee_s *attendee = NULL;
+
+       attendee = (cal_attendee_s *)(record);
+       retvm_if(NULL == attendee, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: cal_alarm_s is NULL");
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s ("
+                       "event_id, "
+                       "attendee_name, attendee_email, attendee_number, "
+                       "attendee_status, attendee_type, attendee_ct_index, "
+                       "attendee_role, attendee_rsvp, attendee_group, "
+                       "attendee_delegator_uri, attendee_delegate_uri, attendee_uid "
+                       ") VALUES ( "
+                       "%d, "
+                       "?, ?, ?, "
+                       "%d, %d, %d, "
+                       "%d, %d, ?, "
+                       "?, ?, ? )",
+                       CAL_TABLE_ATTENDEE,
+                       attendee->event_id,
+                       attendee->attendee_status,
+                       attendee->attendee_type,
+                       attendee->attendee_ct_index,
+                       attendee->attendee_role,
+                       attendee->attendee_rsvp);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       index = 1;
+       if (attendee->attendee_name)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_name);
+       index++;
+
+       if (attendee->attendee_email)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_email);
+       index++;
+
+       if (attendee->attendee_number)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_number);
+       index++;
+
+       if (attendee->attendee_group)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_group);
+       index++;
+
+       if (attendee->attendee_delegator_uri)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_delegator_uri);
+       index++;
+
+       if (attendee->attendee_delegate_uri)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_delegate_uri);
+       index++;
+
+       if (attendee->attendee_uid)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_uid);
+       index++;
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_get_record(int id, calendar_record_h* out_record)
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       sqlite3_stmt *stmt = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       int ret = CALENDAR_ERROR_NONE;
+
+       retvm_if(id < 0, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: id(%d)", id);
+
+       ret = calendar_record_create(_calendar_attendee._uri, out_record);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_record_create(%d)", ret);
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+       snprintf(query, sizeof(query),
+                       "SELECT * FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ATTENDEE,
+                       id);
+       stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_record_destroy(*out_record, true);
+        *out_record = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_ROW != dbret)
+       {
+               ERR(" _cal_db_util_stmt_step() Failed(%d)", dbret);
+               sqlite3_finalize(stmt);
+               calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       __cal_db_attendee_get_stmt(stmt,*out_record);
+
+       sqlite3_finalize(stmt);
+       stmt = NULL;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_update_record(calendar_record_h record)
+{
+       int index;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       cal_attendee_s *attendee = NULL;
+       sqlite3_stmt *stmt = NULL;
+
+       attendee = (cal_attendee_s *)(record);
+       retvm_if(NULL == attendee, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: record is NULL");
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET "
+                       "attendee_name = ?, "
+                       "attendee_email = ?, "
+                       "attendee_number = ?, "
+                       "attendee_status = %d, "
+                       "attendee_type = %d, "
+                       "attendee_ct_index = %d, "
+                       "attendee_role = %d, "
+                       "attendee_rsvp = %d, "
+                       "attendee_group = ?, "
+                       "attendee_delegator_uri = ?, "
+                       "attendee_delegate_uri = ?, "
+                       "attendee_uid = ? ",
+                       CAL_TABLE_ATTENDEE,
+                       attendee->attendee_status,
+                       attendee->attendee_type,
+                       attendee->attendee_ct_index,
+                       attendee->attendee_role,
+                       attendee->attendee_rsvp);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED,
+                       "_cal_db_util_query_prepare() Failed");
+
+       index = 1;
+       if (attendee->attendee_name)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_name);
+       index++;
+
+       if (attendee->attendee_email)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_email);
+       index++;
+
+       if (attendee->attendee_number)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_number);
+       index++;
+
+       if (attendee->attendee_group)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_group);
+       index++;
+
+       if (attendee->attendee_delegator_uri)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_delegator_uri);
+       index++;
+
+       if (attendee->attendee_delegate_uri)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_delegate_uri);
+       index++;
+
+       if (attendee->attendee_uid)
+               _cal_db_util_stmt_bind_text(stmt, index, attendee->attendee_uid);
+       index++;
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_delete_record(int id)
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+
+       snprintf(query, sizeof(query),
+                       "DELETE FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ATTENDEE,
+                       id);
+
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_get_all_records(int offset, int limit, calendar_list_h* out_list)
+{
+       int ret;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+       retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter: calendar_list_h is NULL");
+       ret = calendar_list_create(out_list);
+       retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED,
+                       "calendar_list_create() failed");
+
+       if (limit > 0)
+       {
+               snprintf(limitquery, sizeof(limitquery), "LIMIT %d ", limit);
+       }
+       if (offset > 0)
+       {
+               snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d ", offset);
+       }
+       snprintf(query, sizeof(query),
+                       "SELECT * FROM %s %s %s ",
+                       CAL_TABLE_ATTENDEE, limitquery, offsetquery);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() failed");
+               calendar_list_destroy(*out_list, true);
+               *out_list = NULL;
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       calendar_record_h record = NULL;
+
+       while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+       {
+               ret = calendar_record_create(_calendar_attendee._uri, &record);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+                       sqlite3_finalize(stmt);
+                       return ret;
+               }
+               //
+               __cal_db_attendee_get_stmt(stmt,record);
+
+               ret = calendar_list_add(*out_list, record);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+                       calendar_record_destroy(record, true);
+                       sqlite3_finalize(stmt);
+                       return ret;
+               }
+       }
+       sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+    char *table_name;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_ATTENDEE))
+    {
+        table_name = SAFE_STRDUP(CAL_TABLE_ATTENDEE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", table_name);
+    }
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_attendee._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_attendee_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_attendee_get_stmt(stmt,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_insert_records(const calendar_list_h list, int** ids)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_attendee_insert_record(record, NULL) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_update_records(const calendar_list_h list)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_attendee_update_record(record) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_delete_records(int ids[], int count)
+{
+    int i=0;
+    for(i=0;i<count;i++)
+    {
+        if (__cal_db_attendee_delete_record(ids[i]) != CALENDAR_ERROR_NONE)
+        {
+            ERR("delete failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_get_count(int *out_count)
+{
+       int ret;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_ATTENDEE);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_attendee_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_ATTENDEE))
+    {
+        table_name = SAFE_STRDUP(CAL_TABLE_ATTENDEE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_attendee_get_records(int event_id, GList **out_list)
+{
+       int ret;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+       GList *list = NULL;
+
+       retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid parameter: GList is NULL");
+
+       snprintf(query, sizeof(query),
+                       "SELECT * FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ATTENDEE,
+                       event_id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       int index;
+       const unsigned char *temp;
+       calendar_record_h record = NULL;
+       cal_attendee_s *attendee = NULL;
+
+       while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+       {
+               ret = calendar_record_create(_calendar_attendee._uri, &record);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+            sqlite3_finalize(stmt);
+                       return ret;
+               }
+
+               index = 0;
+               attendee = (cal_attendee_s *)(record);
+
+               attendee->event_id = sqlite3_column_int(stmt, index++);
+
+               temp = sqlite3_column_text(stmt, index++);
+               attendee->attendee_name = SAFE_STRDUP(temp);
+
+               temp = sqlite3_column_text(stmt, index++);
+               attendee->attendee_email = SAFE_STRDUP(temp);
+
+               temp = sqlite3_column_text(stmt, index++);
+               attendee->attendee_number = SAFE_STRDUP(temp);
+
+               attendee->attendee_status = sqlite3_column_int(stmt, index++);
+               attendee->attendee_type = sqlite3_column_int(stmt, index++);
+               attendee->attendee_ct_index = sqlite3_column_int(stmt, index++);
+               attendee->attendee_role = sqlite3_column_int(stmt, index++);
+               attendee->attendee_rsvp = sqlite3_column_int(stmt, index++);
+
+               temp = sqlite3_column_text(stmt, index++);
+               attendee->attendee_group = SAFE_STRDUP(temp);
+
+               temp = sqlite3_column_text(stmt, index++);
+               attendee->attendee_delegator_uri = SAFE_STRDUP(temp);
+
+               temp = sqlite3_column_text(stmt, index++);
+               attendee->attendee_delegate_uri = SAFE_STRDUP(temp);
+
+               temp = sqlite3_column_text(stmt, index++);
+               attendee->attendee_uid = SAFE_STRDUP(temp);
+
+               list = g_list_append(list, record);
+       }
+
+       sqlite3_finalize(stmt);
+       *out_list = list;
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_attendee_convert_gtoh(GList *glist, int id, calendar_list_h *hlist)
+{
+       int ret;
+       GList *g = NULL;
+       calendar_list_h h = NULL;
+       calendar_record_h attendee = NULL;
+
+       if (glist == NULL)
+       {
+               DBG("No attendee");
+               return CALENDAR_ERROR_NO_DATA;
+       }
+       ret = calendar_list_create(&h);
+
+       g = g_list_first(glist);
+       while (g)
+       {
+               attendee = (calendar_record_h)g->data;
+               if (attendee)
+               {
+                   ret = _cal_record_set_int(attendee,_calendar_attendee.event_id,id);
+                   ret = calendar_list_add(h, attendee);
+
+               }
+               g = g_list_next(g);
+       }
+
+       *hlist = h;
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_attendee_delete_with_id(int event_id)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    snprintf(query, sizeof(query), "DELETE FROM %s WHERE event_id=%d ",
+            CAL_TABLE_ATTENDEE, event_id);
+
+    dbret = _cal_db_util_query_exec(query);
+    if (dbret != CAL_DB_OK)
+       {
+        ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_attendee_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
+{
+    cal_attendee_s *attendee = NULL;
+    int index;
+    const unsigned char *temp;
+
+    attendee = (cal_attendee_s*)(record);
+    index = 0;
+
+    attendee->event_id = sqlite3_column_int(stmt, index++);
+
+    temp = sqlite3_column_text(stmt, index++);
+    attendee->attendee_name = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, index++);
+    attendee->attendee_email = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, index++);
+    attendee->attendee_number = SAFE_STRDUP(temp);
+
+    attendee->attendee_status = sqlite3_column_int(stmt, index++);
+    attendee->attendee_type = sqlite3_column_int(stmt, index++);
+    attendee->attendee_ct_index = sqlite3_column_int(stmt, index++);
+    attendee->attendee_role = sqlite3_column_int(stmt, index++);
+    attendee->attendee_rsvp = sqlite3_column_int(stmt, index++);
+
+    temp = sqlite3_column_text(stmt, index++);
+    attendee->attendee_group = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, index++);
+    attendee->attendee_delegator_uri = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, index++);
+    attendee->attendee_delegate_uri = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, index++);
+    attendee->attendee_uid = SAFE_STRDUP(temp);
+}
+
+static void __cal_db_attendee_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record)
+{
+    cal_attendee_s *attendee = NULL;
+    const unsigned char *temp;
+
+    attendee = (cal_attendee_s*)(record);
+
+    switch(property)
+    {
+    case CAL_PROPERTY_ATTENDEE_NUMBER:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        attendee->attendee_number = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ATTENDEE_TYPE:
+        attendee->attendee_type = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ATTENDEE_CT_INDEX:
+        attendee->attendee_ct_index = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ATTENDEE_UID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        attendee->attendee_uid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ATTENDEE_GROUP:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        attendee->attendee_group = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ATTENDEE_EMAIL:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        attendee->attendee_email = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ATTENDEE_ROLE:
+        attendee->attendee_role = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ATTENDEE_STATUS:
+        attendee->attendee_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ATTENDEE_RSVP:
+        attendee->attendee_rsvp = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_ATTENDEE_DELEGATE_URI:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        attendee->attendee_delegate_uri = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ATTENDEE_DELEGATOR_URI:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        attendee->attendee_delegator_uri = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ATTENDEE_NAME:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        attendee->attendee_name = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_ATTENDEE_EVENT_ID:
+        attendee->event_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    default:
+        sqlite3_column_int(stmt, *stmt_count);
+        break;
+    }
+    *stmt_count = *stmt_count+1;
+}
+
+static void __cal_db_attendee_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_attendee_get_property_stmt(stmt,projection[i],&stmt_count,record);
+    }
+}
diff --git a/native/cal_db_attendee.h b/native/cal_db_attendee.h
new file mode 100644 (file)
index 0000000..064cd57
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_ATTENDEE_H__
+#define __CALENDAR_SVC_DB_ATTENDEE_H__
+
+#include "cal_db.h"
+
+int _cal_db_attendee_get_records(int event_id, GList **out_list);
+int _cal_db_attendee_convert_gtoh(GList *glist, int id, calendar_list_h *hlist);
+int _cal_db_attendee_delete_with_id(int event_id);
+
+#endif  //__CALENDAR_SVC_DB_ATTENDEE_H__
diff --git a/native/cal_db_extended.c b/native/cal_db_extended.c
new file mode 100644 (file)
index 0000000..6c6ba0a
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db.h"
+#include "cal_db_util.h"
+#include "cal_db_query.h"
+#include "cal_db_extended.h"
+
+int _cal_db_extended_get_records(int record_id, calendar_record_type_e record_type, GList **out_list)
+{
+    int ret;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    GList *list = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter: GList is NULL");
+
+    snprintf(query, sizeof(query),
+            "SELECT * FROM %s "
+            "WHERE record_id = %d AND "
+            "record_type = %d",
+            CAL_TABLE_EXTENDED,
+            record_id,
+            record_type);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    int count = 0;
+    const unsigned char *temp;
+    calendar_record_h record = NULL;
+    cal_extended_s *extended = NULL;
+
+    while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        ret = calendar_record_create(_calendar_extended_property._uri, &record);
+        if (CALENDAR_ERROR_NONE != ret)
+        {
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+
+        count = 0;
+        extended = (cal_extended_s *)(record);
+
+        extended->id = sqlite3_column_int(stmt, count++);
+        extended->record_id = sqlite3_column_int(stmt, count++);
+        extended->record_type = sqlite3_column_int(stmt, count++);
+        temp = sqlite3_column_text(stmt, count++);
+        extended->key = SAFE_STRDUP(temp);
+        temp = sqlite3_column_text(stmt, count++);
+        extended->value = SAFE_STRDUP(temp);
+
+        list = g_list_append(list, record);
+    }
+    sqlite3_finalize(stmt);
+
+    *out_list = list;
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_extended_convert_gtoh(GList *glist, int record_id, calendar_record_type_e record_type, calendar_list_h *hlist)
+{
+    int ret;
+    GList *g = NULL;
+    calendar_list_h h = NULL;
+    calendar_record_h extended = NULL;
+
+    if (glist == NULL)
+    {
+        DBG("No attendee");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    ret = calendar_list_create(&h);
+
+    g = g_list_first(glist);
+    while (g)
+    {
+        extended = (calendar_record_h)g->data;
+        if (extended)
+        {
+            ret = _cal_record_set_int(extended,_calendar_extended_property.record_id,record_id);
+            ret = _cal_record_set_int(extended,_calendar_extended_property.record_type,record_type);
+            ret = calendar_list_add(h, extended);
+        }
+        g = g_list_next(g);
+    }
+
+    *hlist = h;
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_extended_delete_with_id(int record_id, calendar_record_type_e record_type)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    snprintf(query, sizeof(query), "DELETE FROM %s WHERE record_id=%d AND record_type=%d",
+            CAL_TABLE_EXTENDED, record_id, record_type);
+
+    dbret = _cal_db_util_query_exec(query);
+    if (dbret != CAL_DB_OK) {
+        ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/native/cal_db_extended.h b/native/cal_db_extended.h
new file mode 100644 (file)
index 0000000..56b9ca8
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_EXTENDED_H__
+#define __CALENDAR_SVC_DB_EXTENDED_H__
+
+int _cal_db_extended_get_records(int record_id, calendar_record_type_e record_type, GList **out_list);
+int _cal_db_extended_convert_gtoh(GList *glist, int record_id, calendar_record_type_e record_type, calendar_list_h *hlist);
+int _cal_db_extended_delete_with_id(int record_id, calendar_record_type_e record_type);
+
+#endif  //__CALENDAR_SVC_DB_EXTENDED_H__
diff --git a/native/cal_db_instance.c b/native/cal_db_instance.c
new file mode 100644 (file)
index 0000000..5f4578b
--- /dev/null
@@ -0,0 +1,1968 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdlib.h>
+#include <glib.h>
+#include <unicode/ucal.h>
+#include <unicode/ustring.h>
+#include <unicode/ustdio.h>
+#include <unicode/udat.h>
+#include <sys/types.h>
+
+#include "calendar_db.h"
+#include "calendar_types2.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_time.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+
+#define ms2sec(ms) (long long int)(ms / 1000.0)
+#define sec2ms(s) (s * 1000.0)
+
+/* input order
+   UCAL_MONTH + UCAL_DAY_OF_MONTH
+   UCAL_MONTH + UCAL_WEEK_OF_MONTH + UCAL_DAY_OF_WEEK
+   UCAL_MONTH + UCAL_DAY_OF_WEEK_IN_MONTH + UCAL_DAY_OF_WEEK
+   UCAL_DAY_OF_YEAR
+   UCAL_DAY_OF_WEEK + UCAL_WEEK_OF_YEAR
+*/
+
+struct day {
+       int uday;
+       const char *str;
+};
+
+#define CAL_ENDLESS_LIMIT_YEAR 2038
+#define CAL_ENDLESS_LIMIT_MONTH 12
+#define CAL_ENDLESS_LIMIT_MDAY 31
+
+static struct day wdays[] = {
+       [CALENDAR_SUNDAY] = {UCAL_SUNDAY, "SU"},
+       [CALENDAR_MONDAY] = {UCAL_MONDAY, "MO"},
+       [CALENDAR_TUESDAY] = {UCAL_TUESDAY, "TU"},
+       [CALENDAR_WEDNESDAY] = {UCAL_WEDNESDAY, "WE"},
+       [CALENDAR_THURSDAY] = {UCAL_THURSDAY, "TH"},
+       [CALENDAR_FRIDAY] = {UCAL_FRIDAY, "FR"},
+       [CALENDAR_SATURDAY] = {UCAL_SATURDAY, "SA"},
+};
+
+static void __cal_db_instance_print_ucal(UCalendar *ucal)
+{
+       long long int lli;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (ucal)
+       {
+               lli = ms2sec(ucal_getMillis(ucal, &ec));
+               DBG("(%d)", lli);
+       }
+}
+
+static int __cal_db_instance_work_normal_setpos(int event_id, long long int lli_s, long long int lli_e, char **t)
+{
+       int i, j;
+       int ret;
+       int count = 0;
+       int ids[366] = {0};
+       char str_option[CAL_DB_SQL_MAX_LEN] = {0};
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char str_fraction[64] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       j = -1;
+       for (i = 0; t[i];i++)
+       {
+               snprintf(query, sizeof(query), "SELECT rowid FROM %s "
+                               "WHERE event_id = %d "
+                               "AND dtstart_utime >= %lld AND dtend_utime < %lld "
+                               "ORDER BY dtstart_utime "
+                               "LIMIT %d, 1 ",
+                               CAL_TABLE_NORMAL_INSTANCE,
+                               event_id,
+                               lli_s, lli_e,
+                               atoi(t[i]) - 1);
+               ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_db_util_query_get_first_int_result() failed");
+                       return ret;
+               }
+               if (count <= 0)
+               {
+                       DBG("%s", query);
+                       DBG("no result");
+                       continue;
+               }
+               else
+               {
+                       j++;
+                       ids[j] = count;
+                       DBG("append result");
+               }
+               DBG("[%lld] ~ [%lld] setpos id(%d)", lli_s, lli_e, ids[j]);
+       }
+
+       while (j >= 0)
+       {
+               snprintf(str_fraction, sizeof(str_fraction), "AND rowid != %d ", ids[j]);
+               DBG("fra:%s", str_fraction);
+               strcat(str_option, str_fraction);
+               DBG("opt:%s", str_option);
+               j--;
+       }
+       DBG("str_option[%s]", str_option);
+       snprintf(query, sizeof(query), "DELETE FROM %s "
+                       "WHERE event_id = %d "
+                       "AND dtstart_utime>= %lld AND dtend_utime < %lld "
+                       "%s",
+                       CAL_TABLE_NORMAL_INSTANCE,
+                       event_id,
+                       lli_s, lli_e,
+                       str_option);
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_work_allday_setpos(int event_id, char *str_s, char *str_e, char **t)
+{
+       int i, j;
+       int ret;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       int count = 0;
+       int ids[366] = {0};
+       char str_option[CAL_DB_SQL_MAX_LEN] = {0};
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char str_fraction[64] = {0};
+
+       j = -1;
+       for (i = 0; t[i];i++)
+       {
+               snprintf(query, sizeof(query), "SELECT rowid FROM %s "
+                               "WHERE event_id = %d "
+                               "AND dtstart_datetime >= %s AND dtend_datetime < %s "
+                               "ORDER BY dtstart_datetime "
+                               "LIMIT %d, 1 ",
+                               CAL_TABLE_ALLDAY_INSTANCE,
+                               event_id,
+                               str_s, str_e,
+                               atoi(t[i]) - 1);
+               ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_db_util_query_get_first_int_result() failed");
+                       return ret;
+               }
+               if (count <= 0)
+               {
+                       DBG("%s", query);
+                       DBG("no result");
+                       continue;
+               }
+               else
+               {
+                       j++;
+                       ids[j] = count;
+                       DBG("append result");
+               }
+               DBG("[%s] ~ [%s] setpos id(%d)", str_s, str_e, ids[j]);
+       }
+
+       while (j >= 0)
+       {
+               snprintf(str_fraction, sizeof(str_fraction), "AND rowid != %d ", ids[j]);
+               DBG("fra:%s", str_fraction);
+               strcat(str_option, str_fraction);
+               DBG("opt:%s", str_option);
+               j--;
+       }
+       DBG("str_option[%s]", str_option);
+       snprintf(query, sizeof(query), "DELETE FROM %s "
+                       "WHERE event_id = %d "
+                       "AND dtstart_datetime >= %s AND dtend_datetime < %s "
+                       "%s",
+                       CAL_TABLE_ALLDAY_INSTANCE,
+                       event_id,
+                       str_s, str_e,
+                       str_option);
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_apply_setpos(int event_id, calendar_time_s *st, cal_event_s *event, int freq)
+{
+       int ret;
+       int count;
+       int index;
+       int y, m, d;
+       int y1, m1, d1;
+       long long int lli_s = 0, lli_e = 0;
+       char **t;
+       const char *dl = ",";
+       char str_t[32] = {0};
+       char str_s[32] = {0};
+       char str_e[32] = {0};
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       UCalendar *ucal;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       t = g_strsplit(event->bysetpos, dl, -1);
+       if (!t)
+       {
+               ERR("g_strsplit failed");
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       switch (st->type)
+       {
+       case CALENDAR_TIME_UTIME:
+               DBG("(%lld)", st->time.utime);
+               snprintf(query, sizeof(query), "SELECT count(*) FROM %s "
+                               "WHERE event_id = %d "
+                               "AND dtstart_utime >= %lld",
+                               CAL_TABLE_NORMAL_INSTANCE,
+                               event_id,
+                               st->time.utime);
+               ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_db_util_query_get_first_int_result() failed");
+                       g_strfreev(t);
+                       return ret;
+               }
+               DBG("count(%d)", count);
+               index = 0;
+
+               while (count > 0)
+               {
+                       ucal = _cal_time_get_ucal(event->start_tzid, event->wkst);
+                       ucal_setMillis(ucal, sec2ms(st->time.utime), &ec);
+                       switch (freq)
+                       {
+                       case CALENDAR_RECURRENCE_YEARLY:
+                               ucal_add(ucal, UCAL_YEAR, index, &ec);
+                               ucal_set(ucal, UCAL_MONTH, 1);
+                               ucal_set(ucal, UCAL_DATE, 1);
+                               lli_s = ms2sec(ucal_getMillis(ucal, &ec));
+
+                               ucal_add(ucal, UCAL_YEAR, 1, &ec);
+                               lli_e = ms2sec(ucal_getMillis(ucal, &ec));
+                               break;
+
+                       case CALENDAR_RECURRENCE_MONTHLY:
+                               ucal_add(ucal, UCAL_MONTH, index, &ec);
+                               ucal_set(ucal, UCAL_DATE, 1);
+                               lli_s = ms2sec(ucal_getMillis(ucal, &ec));
+
+                               ucal_add(ucal, UCAL_MONTH, 1, &ec);
+                               lli_e = ms2sec(ucal_getMillis(ucal, &ec));
+                               break;
+
+                       case CALENDAR_RECURRENCE_WEEKLY:
+                               ucal_add(ucal, UCAL_DATE, (7 * index), &ec);
+                               ucal_set(ucal, UCAL_DAY_OF_WEEK, 1);
+                               lli_s = ms2sec(ucal_getMillis(ucal, &ec));
+
+                               ucal_add(ucal, UCAL_DATE, 7, &ec);
+                               lli_e = ms2sec(ucal_getMillis(ucal, &ec));
+                               break;
+
+                       default:
+                               break;
+                       }
+                       ucal_close(ucal);
+
+                       DBG("%lld %lld", lli_s, lli_e);
+                       __cal_db_instance_work_normal_setpos(event_id, lli_s, lli_e, t);
+                       snprintf(query, sizeof(query), "SELECT count(*) FROM %s "
+                                       "WHERE event_id = %d "
+                                       "AND dtstart_utime >= %lld",
+                                       CAL_TABLE_NORMAL_INSTANCE,
+                                       event_id,
+                                       lli_e);
+                       ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+                       if (CALENDAR_ERROR_NONE != ret)
+                       {
+                               ERR("_cal_db_util_query_get_first_int_result() failed");
+                               g_strfreev(t);
+                               return ret;
+                       }
+                       DBG("setpos left count(%d) from [%lld]", count, lli_e);
+                       index++;
+               }
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               y = st->time.date.year;
+               m = st->time.date.month;
+               d = st->time.date.mday;
+               DBG("%d/%d/%d", y, m, d);
+               snprintf(str_t, sizeof(str_t), "%04d%02d%02d", y, m, d);
+               snprintf(query, sizeof(query), "SELECT count(*) FROM %s "
+                               "WHERE event_id = %d "
+                               "AND dtstart_datetime >= %s",
+                               CAL_TABLE_ALLDAY_INSTANCE,
+                               event_id,
+                               str_t);
+               ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_db_util_query_get_first_int_result() failed");
+                       g_strfreev(t);
+                       return ret;
+               }
+               DBG("count(%d)", count);
+               index = 0;
+
+               while (count > 0)
+               {
+                       // _cal_db_instance_get_next_period(event, str_s, str_e, index);
+                       switch (freq)
+                       {
+                       case CALENDAR_RECURRENCE_YEARLY:
+                               snprintf(str_s, sizeof(str_s), "%04d%02d%02d", y + index, 1, 1);
+                               snprintf(str_e, sizeof(str_e), "%04d%02d%02d", y + index + 1, 1, 1);
+                               break;
+
+                       case CALENDAR_RECURRENCE_MONTHLY:
+                               snprintf(str_s, sizeof(str_s), "%04d%02d%02d",
+                                               y + ((m + index) / 13),
+                                               (m + index) % 13 == 0 ? 1 : (m + index) % 13,
+                                               1);
+                               snprintf(str_e, sizeof(str_e), "%04d%02d%02d",
+                                               y + ((m + index + 1) / 13),
+                                               (m + index + 1) % 13 == 0 ? 1 : (m + index + 1) % 13,
+                                               1);
+                               break;
+
+                       case CALENDAR_RECURRENCE_WEEKLY:
+                               ucal = _cal_time_get_ucal(event->start_tzid, event->wkst);
+                               ucal_setDate(ucal, y, m - 1, d + (7 * index), &ec);
+                               y1 = ucal_get(ucal, UCAL_YEAR, &ec);
+                               m1 = ucal_get(ucal, UCAL_MONTH, &ec) + 1;
+                               d1 = ucal_get(ucal, UCAL_DATE, &ec);
+                               DBG("start(%d/%d/%d", y1, m1, d1);
+                               ucal_set(ucal, UCAL_DAY_OF_WEEK, 1);
+                               y1 = ucal_get(ucal, UCAL_YEAR, &ec);
+                               m1 = ucal_get(ucal, UCAL_MONTH, &ec) + 1;
+                               d1 = ucal_get(ucal, UCAL_DATE, &ec);
+                               snprintf(str_s, sizeof(str_s), "%04d%02d%02d",
+                                               y1, m1, d1);
+                               DBG("start(%d/%d/%d", y1, m1, d1);
+
+                               ucal_add(ucal, UCAL_DATE, 7, &ec);
+                               y1 = ucal_get(ucal, UCAL_YEAR, &ec);
+                               m1 = ucal_get(ucal, UCAL_MONTH, &ec) + 1;
+                               d1 = ucal_get(ucal, UCAL_DATE, &ec);
+                               snprintf(str_e, sizeof(str_e), "%04d%02d%02d",
+                                               y1, m1, d1);
+                               DBG("end(%d/%d/%d", y1, m1, d1);
+                               ucal_close(ucal);
+                               break;
+
+                       case CALENDAR_RECURRENCE_DAILY:
+                               DBG("Not support setpos in daily");
+                               break;
+
+                       default:
+                               break;
+                       }
+
+                       __cal_db_instance_work_allday_setpos(event_id, str_s, str_e, t);
+
+                       snprintf(query, sizeof(query), "SELECT count(*) FROM %s "
+                                       "WHERE event_id = %d "
+                                       "AND dtstart_datetime >= %s",
+                                       CAL_TABLE_ALLDAY_INSTANCE,
+                                       event_id,
+                                       str_e);
+//                     DBG("%s", query);
+                       ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+                       if (CALENDAR_ERROR_NONE != ret)
+                       {
+                               ERR("_cal_db_util_query_get_first_int_result() failed");
+                               g_strfreev(t);
+                               return ret;
+                       }
+                       DBG("setpos left count(%d) from [%s]", count, str_e);
+                       index++;
+               }
+               break;
+
+       default:
+               break;
+       }
+       g_strfreev(t);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_update_exdate_del(int id, char *exdate)
+{
+       int dbret;
+       int i, j;
+       int y, mon, d, h, min, s;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       const char *dl = ",";
+       char **t = NULL;
+       char *p = NULL;
+
+       if (exdate == NULL)
+       {
+               DBG("Nothing to update exdate del");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       DBG("exdate [%s]", exdate);
+       t = g_strsplit(exdate, dl, -1);
+       if (!t)
+       {
+               ERR("g_strsplit failed");
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       for (i = 0; t[i]; i++)
+       {
+               p = t[i];
+               // remove space
+               j = 0;
+               while (p[j] == ' ')
+               {
+                       j++;
+               }
+               p = t[i] + j;
+               DBG("exdate[%s]", p);
+
+               if (strlen(p) > strlen("YYYYMMDD"))
+               {
+                       DBG("NORMAL instance");
+                       sscanf(p, "%04d%02d%02dT%02d%02d%02dZ",
+                                       &y, &mon, &d, &h, &min, &s);
+                       snprintf(query, sizeof(query),
+                                       "DELETE FROM %s "
+                                       "WHERE event_id = %d AND dtstart_utime = %lld ",
+                                       CAL_TABLE_NORMAL_INSTANCE,
+                                       id, _cal_time_convert_itol(NULL, y, mon, d, h, min, s));
+                       DBG("(%lld)", _cal_time_convert_itol(NULL, y, mon, d, h, min, s));
+               }
+               else
+               {
+                       DBG("ALLDAY instance");
+                       snprintf(query, sizeof(query),
+                                       "DELETE FROM %s "
+                                       "WHERE event_id = %d AND dtstart_datetime = %s ",
+                                       CAL_TABLE_ALLDAY_INSTANCE,
+                                       id, p);
+
+               }
+               dbret = _cal_db_util_query_exec(query);
+               if (dbret != CAL_DB_OK) {
+                       ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+                       g_strfreev(t);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+       }
+       g_strfreev(t);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_update_exdate_mod(int original_event_id, char *recurrence_id)
+{
+       int dbret;
+       int i, j;
+       int y, mon, d, h, min, s;
+       const char *dl = ",";
+       char **t = NULL;
+       char *p = NULL;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+
+       if (original_event_id < 1 || recurrence_id == NULL)
+       {
+               DBG("Nothing to update exdate mod");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       DBG("recurrence_id[%s]", recurrence_id);
+       t = g_strsplit(recurrence_id, dl, -1);
+       if (!t)
+       {
+               ERR("g_strsplit failed");
+               return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       for (i = 0; t[i]; i++)
+       {
+               p = t[i];
+               // remove space
+               j = 0;
+               while (p[j] == ' ')
+               {
+                       j++;
+               }
+               p = t[i] + j;
+               DBG("%d[%s]", i + 1, p);
+
+               if (strlen(p) > strlen("YYYYMMDD"))
+               {
+                       DBG("NORMAL instance");
+                       sscanf(p, "%04d%02d%02dT%02d%02d%02dZ",
+                                       &y, &mon, &d, &h, &min, &s);
+                       snprintf(query, sizeof(query),
+                                       "DELETE FROM %s "
+                                       "WHERE event_id = %d AND dtstart_utime = %lld ",
+                                       CAL_TABLE_NORMAL_INSTANCE,
+                                       original_event_id, _cal_time_convert_itol(NULL, y, mon, d, h, min, s));
+                       DBG("(%lld)", _cal_time_convert_itol(NULL, y, mon, d, h, min, s));
+               }
+               else
+               {
+                       DBG("ALLDAY instance");
+                       snprintf(query, sizeof(query),
+                                       "DELETE FROM %s "
+                                       "WHERE event_id = %d AND dtstart_datetime = %s ",
+                                       CAL_TABLE_ALLDAY_INSTANCE,
+                                       original_event_id, p);
+
+               }
+               dbret = _cal_db_util_query_exec(query);
+               if (dbret != CAL_DB_OK) {
+                       ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+                       g_strfreev(t);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+       }
+       g_strfreev(t);
+       return CALENDAR_ERROR_NONE;
+}
+
+static inline int ___cal_db_instance_has_after(calendar_time_s *t1, calendar_time_s *t2)
+{
+       if (t1->type == CALENDAR_TIME_UTIME) {
+               if (t1->time.utime > t2->time.utime)
+                       return 1;
+               else
+                       return 0;
+       }
+
+       DBG("%d %d %d /%d %d %d", t1->time.date.year, t1->time.date.month, t1->time.date.mday,
+                       t2->time.date.year, t2->time.date.month, t2->time.date.mday);
+       if (t1->time.date.year > t2->time.date.year) {
+               DBG("exit year");
+               return 1;
+       } else if (t1->time.date.year < t2->time.date.year) {
+               return 0;
+       } else {
+               if (t1->time.date.month > t2->time.date.month) {
+                       return 1;
+               } else if (t1->time.date.month < t2->time.date.month) {
+                       return 0;
+               } else {
+                       if (t1->time.date.mday > t2->time.date.mday) {
+                               return 1;
+                       } else {
+                               return 0;
+                       }
+               }
+       }
+}
+
+static inline int __cal_db_instance_convert_mday(const char *str, int *mday)
+{
+       int d;
+
+       if (!str || !*str) {
+               ERR("Invalid argument: check mday[%s]", str);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       d = atoi(str);
+       if (d < 1 || d > 31) {
+               ERR("Invalid argument: check day(%d)", d);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       DBG("get mday[%s] and convert to int(%d)", str, d);
+       *mday = d;
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_del_inundant(int event_id, calendar_time_s *st, cal_event_s *event)
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       int cnt;
+       char query[CAL_DB_SQL_MAX_LEN];
+
+       if (event->range_type != CALENDAR_RANGE_COUNT) {
+               return CALENDAR_ERROR_NONE;
+       }
+
+       cnt = event->count;
+       DBG("get count(%d) and del after this", cnt);
+
+       if (st->type == CALENDAR_TIME_UTIME) {
+               snprintf(query, sizeof(query), "DELETE FROM %s "
+                               "WHERE event_id = %d "
+                               "AND dtstart_utime > (SELECT dtstart_utime FROM %s "
+                               "WHERE event_id = %d ORDER BY dtstart_utime LIMIT %d, 1) ",
+                               CAL_TABLE_NORMAL_INSTANCE,
+                               event_id,
+                               CAL_TABLE_NORMAL_INSTANCE,
+                               event_id, cnt -1);
+
+       } else if (st->type == CALENDAR_TIME_LOCALTIME) {
+               snprintf(query, sizeof(query), "DELETE FROM %s "
+                               "WHERE event_id = %d "
+                               "AND dtstart_datetime > (SELECT dtstart_datetime FROM %s "
+                               "WHERE event_id = %d ORDER BY dtstart_datetime LIMIT %d, 1) ",
+                               CAL_TABLE_ALLDAY_INSTANCE,
+                               event_id,
+                               CAL_TABLE_ALLDAY_INSTANCE,
+                               event_id, cnt -1);
+       }
+
+       dbret = _cal_db_util_query_exec(query);
+       if (dbret != CAL_DB_OK)
+       {
+               DBG("query(%s)", query);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_instance_print_caltime(calendar_time_s *caltime)
+{
+       if (caltime) {
+               switch (caltime->type) {
+               case CALENDAR_TIME_UTIME:
+                       DBG("utime(%lld)", caltime->time.utime);
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       DBG("datetime(%04d/%02d/%02d)",
+                                       caltime->time.date.year, caltime->time.date.month, caltime->time.date.mday);
+                       break;
+               }
+       }
+}
+
+static int __cal_db_instance_get_duration(UCalendar *ucal, calendar_time_s *st, calendar_time_s *et, int *duration)
+{
+       int _duration = -1;
+       UErrorCode ec = U_ZERO_ERROR;
+       UDate ud;
+
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL == st || NULL == et)
+       {
+               ERR("Invalid parameter: calendar_time_s is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (st->type) {
+       case CALENDAR_TIME_UTIME:
+               if (st->time.utime > et->time.utime)
+               {
+                       ERR("check time: start(%lld) > end(%lld)", st->time.utime, et->time.utime);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               _duration = (int)(et->time.utime - st->time.utime);
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               ucal_setDateTime(ucal, et->time.date.year, et->time.date.month -1, et->time.date.mday, 0, 0, 0, &ec);
+               ud = ucal_getMillis(ucal, &ec);
+
+               ucal_setDateTime(ucal, st->time.date.year, st->time.date.month -1, st->time.date.mday, 0, 0, 0, &ec);
+
+               _duration = ucal_getFieldDifference(ucal, ud, UCAL_DATE, &ec);
+               if (U_FAILURE(ec))
+               {
+                       ERR("ucal_getFieldDifference failed (%s)", u_errorName(ec));
+                       return ec;
+               }
+               break;
+       }
+
+       if (duration) *duration = _duration;
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_parse_byday(const char *byday, int *nth, int *wday)
+{
+       int _nth = 0;
+       int _wday = 0;
+       char buf[3] = {0};
+
+       if (NULL == byday || strlen(byday) == 0)
+       {
+               ERR("Invalid parameter: byday is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       if (!sscanf(byday, "%d", &_nth)) {
+               DBG("no digit in front of byday, so set 1 as default");
+               if (sscanf(byday, "%s", buf) != 1) {
+                       ERR("Failed to get byday[%s]", byday);
+                       return -1;
+               }
+               _nth = 1;
+       } else {
+               if (sscanf(byday, "%d%s", &_nth, buf) != 2) {
+                       ERR("Failed to get byday[%s]", byday);
+                       return -1;
+               }
+       }
+       buf[2] = '\0';
+
+       // CALENDAR_SUNDAY
+       for (_wday = CALENDAR_SUNDAY; _wday <= CALENDAR_SATURDAY; _wday++) {
+               if (!strncmp(wdays[_wday].str, buf, 2)) {
+                       DBG("inserted nth(%d) wday[%s]", _nth, wdays[_wday].str);
+                       break;
+               }
+       }
+
+       if (nth) *nth = _nth > 4 ? -1 : _nth;
+       if (wday) *wday = _wday;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_instance_set_ucal_start(UCalendar *ucal, calendar_time_s *st)
+{
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (ucal)
+       {
+               switch (st->type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       ucal_setMillis(ucal, sec2ms(st->time.utime), &ec);
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       ucal_setDate(ucal, st->time.date.year,
+                                       st->time.date.month -1, st->time.date.mday, &ec);
+                       break;
+               }
+       }
+}
+
+static void __cal_db_instance_set_wday(UCalendar *ucal, int nth, int wday)
+{
+       if (ucal)
+       {
+               if (nth > 0) ucal_set(ucal, UCAL_DAY_OF_WEEK, wday);
+               if (wday > 0) ucal_set(ucal, UCAL_DAY_OF_WEEK_IN_MONTH, nth);
+       }
+}
+
+static int __cal_db_instance_insert_record(UCalendar *ucal, int duration, int type, int event_id)
+{
+       int ret;
+       long long int lli;
+       UErrorCode ec = U_ZERO_ERROR;
+       calendar_record_h record = NULL;
+       calendar_time_s st = {0};
+       calendar_time_s et = {0};
+       UCalendar *ucal2 = NULL;
+
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (type)
+       {
+       case CALENDAR_TIME_UTIME:
+               lli =  ms2sec(ucal_getMillis(ucal, &ec));
+
+               st.type = type;
+               st.time.utime = lli;
+               DBG("insert normal (%lld)%04d-%02d-%02d %02d:%02d:00",
+                               st.time.utime,
+                               ucal_get(ucal, UCAL_YEAR, &ec),
+                               ucal_get(ucal, UCAL_MONTH, &ec) +1,
+                               ucal_get(ucal, UCAL_DATE, &ec),
+                               ucal_get(ucal, UCAL_HOUR_OF_DAY, &ec),
+                               ucal_get(ucal, UCAL_MINUTE, &ec));
+               et.type = type;
+               et.time.utime = lli + (long long int)duration;
+
+               ret = calendar_record_create(_calendar_instance_normal._uri, &record);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_create() failed");
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+               _cal_record_set_int(record, _calendar_instance_normal.event_id, event_id);
+               ret = _cal_record_set_caltime(record, _calendar_instance_normal.start_time, st);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_record_set_caltime() failed");
+                       return ret;
+               }
+               ret = _cal_record_set_caltime(record, _calendar_instance_normal.end_time, et);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_record_set_caltime() failed");
+                       return ret;
+               }
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               st.type = type;
+               st.time.date.year = ucal_get(ucal, UCAL_YEAR, &ec);
+               st.time.date.month = ucal_get(ucal, UCAL_MONTH, &ec) +1;
+               st.time.date.mday = ucal_get(ucal, UCAL_DATE, &ec);
+               DBG("insert allday %04d-%02d-%02d",
+                               st.time.date.year, st.time.date.month, st.time.date.mday);
+               et.type = type;
+               if (duration > 0)
+               {
+                       ucal2 = ucal_clone(ucal, &ec);
+                       ucal_add(ucal2, UCAL_DATE, duration, &ec);
+                       et.time.date.year = ucal_get(ucal2, UCAL_YEAR, &ec);
+                       et.time.date.month = ucal_get(ucal2, UCAL_MONTH, &ec) +1;
+                       et.time.date.mday = ucal_get(ucal2, UCAL_DATE, &ec);
+                       ucal_close(ucal2);
+               }
+               else
+               {
+                       et.time.date.year = st.time.date.year;
+                       et.time.date.month = st.time.date.month;
+                       et.time.date.mday = st.time.date.mday;
+               }
+
+               ret = calendar_record_create(_calendar_instance_allday._uri, &record);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("calendar_record_create() failed");
+                       return ret;
+               }
+               ret = _cal_record_set_int(record, _calendar_instance_allday.event_id, event_id);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_record_set_int() failed");
+                       return ret;
+               }
+               ret = _cal_record_set_caltime(record, _calendar_instance_allday.start_time, st);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_record_set_caltime() failed");
+                       return ret;
+               }
+               ret = _cal_record_set_caltime(record, _calendar_instance_allday.end_time, et);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_record_set_caltime() failed");
+                       return ret;
+               }
+               break;
+       }
+       ret = calendar_db_insert_record(record, NULL);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_db_insert_record() failed");
+               return ret;
+       }
+       calendar_record_destroy(record, true);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_has_next(UCalendar *ucal, calendar_time_s *until)
+{
+       int has_next = 0;
+       long long int lli = 0;
+       long long int lli2 = 0;
+       UErrorCode ec = U_ZERO_ERROR;
+       UCalendar *ucal2 = NULL;
+
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == until)
+       {
+               ERR("Invalid parameter: until is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (until->type)
+       {
+       case CALENDAR_TIME_UTIME:
+               lli = ms2sec(ucal_getMillis(ucal, &ec));
+               has_next = (lli > until->time.utime) ? 0 : 1;
+               if (has_next == 0)
+               {
+                       DBG("No next:get(%lld) until(%lld)", lli, until->time.utime);
+               }
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               lli = ms2sec(ucal_getMillis(ucal, &ec));
+
+               ucal2 = ucal_clone(ucal, &ec);
+               ucal_setDateTime(ucal2, until->time.date.year, until->time.date.month -1,
+                               until->time.date.mday, 0, 0, 0, &ec);
+               lli2 = ms2sec(ucal_getMillis(ucal2, &ec));
+               ucal_close(ucal2);
+
+               has_next = (lli > lli2) ? 0 : 1;
+               if (has_next == 0)
+               {
+                       DBG("No next:get(%lld) until(%lld)", lli, lli2);
+               }
+               break;
+       }
+
+
+       return has_next;
+}
+
+static int __cal_db_instance_publish_with_wday(UCalendar *ucal, cal_event_s *event, int duration, int field, calendar_time_s *until)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       int i, j;
+       int count = 0;
+       int length = 0;
+       char **t = NULL;
+       const char *d = ",";
+       UDate ud1, ud2;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (event->byday && strlen(event->byday) > 0)
+       {
+               // range: MO, TU, WE, TH, FR, SA, SU ex> 3TH, -1MO
+               t = g_strsplit(event->byday, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       g_strfreev(t);
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+               length = g_strv_length(t);
+       }
+       else
+       {
+               int nth = 0, wday = 0;
+               int nth2;
+               char buf[8] = {0};
+               UCalendar *ucal2 = NULL;
+
+               ucal2 = ucal_clone(ucal, &ec);
+
+               switch (event->start.type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       ucal_setMillis(ucal, sec2ms(event->start.time.utime), &ec);
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       ucal_setDate(ucal2, event->start.time.date.year,
+                                       event->start.time.date.month -1, event->start.time.date.mday, &ec);
+                       break;
+               }
+
+               wday = ucal_get(ucal, UCAL_DAY_OF_WEEK, &ec);
+               wday = wday < UCAL_SUNDAY ? UCAL_SUNDAY : wday;
+
+               nth = ucal_get(ucal2, UCAL_DAY_OF_WEEK_IN_MONTH, &ec);
+               ucal_add(ucal, UCAL_DATE, 7, &ec);
+               nth2 = ucal_get(ucal2, UCAL_DAY_OF_WEEK_IN_MONTH, &ec);
+               nth = (nth2 == 1) ? -1 : nth;
+
+               ucal_close(ucal2);
+
+               snprintf(buf, sizeof(buf), "%d%s", nth, wdays[wday].str);
+               t = g_strsplit(buf, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       g_strfreev(t);
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+               DBG("No byday, so set wday(%s)", t[0]);
+
+               length = 1;
+       }
+       DBG("length(%d)", length);
+
+       if (event->count)
+       {
+               count = event->count;
+
+               if (event->bysetpos)
+               {
+                       int share, remind;
+                       int length2;
+                       char **t2 = NULL;
+
+                       t2 = g_strsplit(event->bysetpos, ",", -1);
+                       length2 = g_strv_length(t2);
+                       g_strfreev(t2);
+
+                       share = length / length2;
+                       remind = length % length2;
+                       count = count * share + (remind ? length : 0);
+               }
+               else
+               {
+                       count = count / length + ((count % length == 0) ? 0 : 1);
+               }
+               DBG("bycount(%d) count(%d)", event->count, count);
+       }
+
+       ud1 = ucal_getMillis(ucal, &ec);
+       int week = ucal_get(ucal, field, &ec);
+
+       for (i = 0; i < length; i++)
+       {
+               // set nth,  wday
+               int nth = 0, wday = 0;
+               ret = __cal_db_instance_parse_byday(t[i], &nth, &wday);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("__cal_db_instance_parse_byday() failed");
+                       g_strfreev(t);
+                       return ret;
+               }
+               ucal_setMillis(ucal, ud1, &ec);
+               switch (field)
+               {
+               case UCAL_WEEK_OF_YEAR:
+                       ucal_set(ucal, field, week);
+                       ucal_set(ucal, UCAL_DAY_OF_WEEK, wday);
+                       break;
+               default:
+                       __cal_db_instance_set_wday(ucal, nth, wday);
+                       break;
+               }
+               DBG("set wday nth(%d) wday(%d)", nth, wday);
+
+               // check whether set ucal goes past or not
+               ud1 = ucal_getMillis(ucal, &ec);
+
+               UCalendar *ucal2 = NULL;
+               ucal2 = ucal_clone(ucal, &ec);
+               __cal_db_instance_set_ucal_start(ucal2, &event->start);
+               ud2 = ucal_getMillis(ucal2, &ec);
+               ucal_close(ucal2);
+
+               if (ms2sec(ud2) > ms2sec(ud1))
+               {
+                       DBG("Invalid first time: start(%lld) get(%lld)", ms2sec(ud2), ms2sec(ud1));
+                       switch (field)
+                       {
+                       case UCAL_WEEK_OF_YEAR:
+                               ucal_add(ucal, field, event->interval, &ec);
+                               break;
+
+                       default:
+                               ucal_add(ucal, field, event->interval, &ec);
+                               __cal_db_instance_set_wday(ucal, nth, wday);
+                               break;
+                       }
+               }
+
+               DBG("range type(%d) interval(%d)", event->range_type, event->interval);
+               switch (event->range_type)
+               {
+               case CALENDAR_RANGE_COUNT:
+                       for (j = 0; j < count; j++)
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                               switch (field)
+                               {
+                               case UCAL_WEEK_OF_YEAR:
+                                       break;
+                               default:
+                                       __cal_db_instance_set_wday(ucal, nth, wday);
+                                       break;
+                               }
+                       }
+                       break;
+
+               case CALENDAR_RANGE_UNTIL:
+               case CALENDAR_RANGE_NONE:
+                       while (__cal_db_instance_has_next(ucal, until))
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                               switch (field)
+                               {
+                               case UCAL_WEEK_OF_YEAR:
+                                       break;
+                               default:
+                                       __cal_db_instance_set_wday(ucal, nth, wday);
+                                       break;
+                               }
+                       }
+                       break;
+               }
+       }
+       g_strfreev(t);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_with_mday(UCalendar *ucal, cal_event_s *event, int duration, int field, calendar_time_s *until)
+{
+       int i;
+       int count = 0;
+       int length = 0;
+       int get_mday;
+       char **t = NULL;
+       const char *d = ",";
+       UDate ud1, ud2;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (event->bymonthday && strlen(event->bymonthday) > 0)
+       {
+               // range: 1, 2, ... , 31 ex> 1, 5, 7
+               t = g_strsplit(event->bymonthday, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       g_strfreev(t);
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+               length = g_strv_length(t);
+               DBG("has bymonthday");
+
+       }
+       else
+       {
+               int mday = 0;
+               char buf[8] = {0};
+               switch (event->start.type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       _cal_time_ltoi(event->start_tzid, event->start.time.utime, NULL, NULL, &mday);
+                       snprintf(buf, sizeof(buf), "%d", mday);
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       snprintf(buf, sizeof(buf), "%d", event->start.time.date.mday);
+                       break;
+               }
+               t = g_strsplit(buf, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       g_strfreev(t);
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+               DBG("No bymonthday, so set mday(%s)", t[0]);
+
+               length = 1;
+       }
+
+       if (event->count)
+       {
+               count = event->count;
+
+               if (event->bysetpos)
+               {
+                       int share, remind;
+                       int length2;
+                       char **t2 = NULL;
+
+                       t2 = g_strsplit(event->bysetpos, ",", -1);
+                       length2 = g_strv_length(t2);
+                       g_strfreev(t2);
+
+                       share = length / length2;
+                       remind = length % length2;
+                       count = count * share + (remind ? length : 0);
+                       DBG("share(%d) remind(%d)", share, remind);
+               }
+               else
+               {
+                       count = count / length + ((count % length == 0) ? 0 : 1);
+               }
+               DBG("count(%d)", count);
+       }
+
+       ud1 = ucal_getMillis(ucal, &ec);
+
+       for (i = 0; i < length; i++)
+       {
+               int mday = atoi(t[i]);
+               DBG("mday is set(%d)", mday);
+               mday = mday < 1 ? mday +1 : mday; // In ICU, last day is 0 not -1.
+
+               ucal_setMillis(ucal, ud1, &ec);
+               ucal_set(ucal, UCAL_DATE, mday);
+
+               // check whether set ucal goes past or not
+               ud1 = ucal_getMillis(ucal, &ec);
+
+               UCalendar *ucal2 = NULL;
+               ucal2 = ucal_clone(ucal, &ec);
+               __cal_db_instance_set_ucal_start(ucal2, &event->start);
+               ud2 = ucal_getMillis(ucal2, &ec);
+               ucal_close(ucal2);
+
+               if (ms2sec(ud2) > ms2sec(ud1))
+               {
+                       DBG("Invalid first time(%lld) > (%lld), so added interval",
+                                       ms2sec(ud2), ms2sec(ud1));
+                       ucal_add(ucal, field, event->interval, &ec);
+               }
+
+               int j = 0, k = 0;
+               DBG("range type(%d)", event->range_type);
+               switch (event->range_type)
+               {
+               case CALENDAR_RANGE_COUNT:
+                       if (count == 1)
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               break;
+                       }
+
+                       for (j = 0; j < count; j++)
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                               if (event->freq != CALENDAR_RECURRENCE_DAILY)
+                               {
+                                       if (mday > 0)
+                                       {
+                                               while ((get_mday = ucal_get(ucal, UCAL_DATE, &ec)) != mday)
+                                               {
+                                                       k++;
+                                                       DBG("Skip this date, we got mday(%d) no match with mday(%d)", get_mday, mday);
+                                                       ucal_setMillis(ucal, ud1, &ec);
+                                                       ucal_set(ucal, UCAL_DATE, mday);
+                                                       ucal_add(ucal, field, event->interval * (j + k), &ec);
+                                                       if ((ucal_get(ucal, UCAL_YEAR, &ec) > CAL_ENDLESS_LIMIT_YEAR) || (k > 50))
+                                                       {
+                                                               ERR("Out of range");
+                                                               j = count;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       else
+                                       {
+                                               ucal_add(ucal, field, event->interval, &ec);
+                                               ucal_set(ucal, UCAL_DATE, mday);
+                                       }
+                               }
+                       }
+                       break;
+
+               case CALENDAR_RANGE_UNTIL:
+               case CALENDAR_RANGE_NONE:
+                       j = 0;
+                       while (__cal_db_instance_has_next(ucal, until))
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                               if (event->freq != CALENDAR_RECURRENCE_DAILY)
+                               {
+                                       if (mday > 0)
+                                       {
+                                               while ((get_mday = ucal_get(ucal, UCAL_DATE, &ec)) != mday)
+                                               {
+                                                       k++;
+                                                       DBG("Skip this date, we got mday(%d) no match with mday(%d)", get_mday, mday);
+                                                       ucal_setMillis(ucal, ud1, &ec);
+                                                       ucal_set(ucal, UCAL_DATE, mday);
+                                                       ucal_add(ucal, field, event->interval * (j + k), &ec);
+                                                       if ((ucal_get(ucal, UCAL_YEAR, &ec) > CAL_ENDLESS_LIMIT_YEAR) || (k > 50))
+                                                       {
+                                                               ERR("Out of range");
+                                                               j = count;
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                                       else
+                                       {
+                                               ucal_add(ucal, field, event->interval, &ec);
+                                               ucal_set(ucal, UCAL_DATE, mday);
+                                       }
+                               }
+                               j++;
+                       }
+                       break;
+               }
+       }
+       g_strfreev(t);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_with_weekno(UCalendar *ucal, cal_event_s *event, int duration, int field, calendar_time_s *until)
+{
+       int i, j;
+       int count = 0;
+       int length = 0;
+       char **t = NULL;
+       const char *d = ",";
+       UDate ud1, ud2;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (event->byweekno && strlen(event->byweekno) > 0)
+       {
+               // range: -366, -1, 1, 366 ex> 3,200
+               t = g_strsplit(event->byweekno, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       g_strfreev(t);
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+               length = g_strv_length(t);
+               DBG("has bymonthday");
+
+       }
+
+       if (event->count)
+       {
+               count = event->count;
+
+               if (event->bysetpos)
+               {
+                       int share, remind;
+                       int length2;
+                       char **t2 = NULL;
+
+                       t2 = g_strsplit(event->bysetpos, ",", -1);
+                       length2 = g_strv_length(t2);
+                       g_strfreev(t2);
+
+                       share = length / length2;
+                       remind = length % length2;
+                       count = count * share + (remind ? length : 0);
+                       DBG("share(%d) remind(%d)", share, remind);
+               }
+               else
+               {
+                       count = count / length + ((count % length == 0) ? 0 : 1);
+                       DBG("length(%d)", length);
+               }
+               DBG("bycount(%d) count(%d)", event->count, count);
+       }
+
+       int wday;
+       wday = ucal_get(ucal, UCAL_DAY_OF_WEEK, &ec);
+       ud1 = ucal_getMillis(ucal, &ec);
+
+       for (i = 0; i < length; i++)
+       {
+               int weekno = atoi(t[i]);
+
+               ucal_setMillis(ucal, ud1, &ec);
+               ucal_set(ucal, UCAL_WEEK_OF_YEAR, weekno);
+               DBG("weekno is set(%d)", weekno);
+
+               // check whether set ucal goes past or not
+               ud1 = ucal_getMillis(ucal, &ec);
+
+               UCalendar *ucal2 = NULL;
+               ucal2 = ucal_clone(ucal, &ec);
+               __cal_db_instance_set_ucal_start(ucal2, &event->start);
+               ud2 = ucal_getMillis(ucal2, &ec);
+               ucal_close(ucal2);
+
+               if (ms2sec(ud2) > ms2sec(ud1))
+               {
+                       DBG("Invalid first time: start(%lld) get(%lld)", ms2sec(ud2), ms2sec(ud1));
+                       ucal_add(ucal, field, 1, &ec);
+               }
+
+               DBG("range type(%d) interval(%d)", event->range_type, event->interval);
+               switch (event->range_type)
+               {
+               case CALENDAR_RANGE_COUNT:
+                       for (j = 0; j < count; j++)
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                       }
+                       break;
+
+               case CALENDAR_RANGE_UNTIL:
+               case CALENDAR_RANGE_NONE:
+                       while (__cal_db_instance_has_next(ucal, until))
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                       }
+                       break;
+               }
+       }
+       g_strfreev(t);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+
+static int __cal_db_instance_publish_with_yday(UCalendar *ucal, cal_event_s *event, int duration, int field, calendar_time_s *until)
+{
+       int i, j;
+       int count = 0;
+       int length = 0;
+       char **t = NULL;
+       const char *d = ",";
+       UDate ud1, ud2;
+       UErrorCode ec = U_ZERO_ERROR;
+
+       if (event->byyearday && strlen(event->byyearday) > 0)
+       {
+               // range: -366, -1, 1, 366 ex> 3,200
+               t = g_strsplit(event->byyearday, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       g_strfreev(t);
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+               length = g_strv_length(t);
+               DBG("has bymonthday");
+
+       }
+
+       if (event->count)
+       {
+               count = event->count;
+
+               if (event->bysetpos)
+               {
+                       int share, remind;
+                       int length2;
+                       char **t2 = NULL;
+
+                       t2 = g_strsplit(event->bysetpos, ",", -1);
+                       length2 = g_strv_length(t2);
+                       g_strfreev(t2);
+
+                       share = length / length2;
+                       remind = length % length2;
+                       count = count * share + (remind ? length : 0);
+                       DBG("share(%d) remind(%d)", share, remind);
+               }
+               else
+               {
+                       count = count / length + ((count % length == 0) ? 0 : 1);
+                       DBG("length(%d)", length);
+               }
+               DBG("bycount(%d) count(%d)", event->count, count);
+       }
+
+       ud1 = ucal_getMillis(ucal, &ec);
+
+       for (i = 0; i < length; i++)
+       {
+               int yday = atoi(t[i]);
+
+               ucal_setMillis(ucal, ud1, &ec);
+               ucal_set(ucal, UCAL_DAY_OF_YEAR, yday);
+               DBG("yday is set(%d)", yday);
+
+               // check whether set ucal goes past or not
+               ud1 = ucal_getMillis(ucal, &ec);
+
+               UCalendar *ucal2 = NULL;
+               ucal2 = ucal_clone(ucal, &ec);
+               __cal_db_instance_set_ucal_start(ucal2, &event->start);
+               ud2 = ucal_getMillis(ucal2, &ec);
+               ucal_close(ucal2);
+
+               if (ms2sec(ud2) > ms2sec(ud1))
+               {
+                       DBG("Invalid first time: start(%lld) get(%lld)", ms2sec(ud2), ms2sec(ud1));
+                       ucal_add(ucal, field, 1, &ec);
+               }
+
+               DBG("range type(%d) interval(%d)", event->range_type, event->interval);
+               switch (event->range_type)
+               {
+               case CALENDAR_RANGE_COUNT:
+                       for (j = 0; j < count; j++)
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                       }
+                       break;
+
+               case CALENDAR_RANGE_UNTIL:
+               case CALENDAR_RANGE_NONE:
+                       while (__cal_db_instance_has_next(ucal, until))
+                       {
+                               __cal_db_instance_insert_record(ucal, duration, event->start.type, event->index);
+                               ucal_add(ucal, field, event->interval, &ec);
+                       }
+                       break;
+               }
+       }
+       g_strfreev(t);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_record_yearly(UCalendar *ucal, cal_event_s *event, int duration, calendar_time_s *until)
+{
+       int i;
+       char **t = NULL;
+       const char *d = ",";
+
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == event)
+       {
+               ERR("Invalid parameter: event is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       __cal_db_instance_set_ucal_start(ucal, &event->start);
+       __cal_db_instance_print_ucal(ucal);
+
+       if (event->bymonth && strlen(event->bymonth) > 0)
+       {
+               // range: 1 ~ 12 ex> 1, 2, 4
+               t = g_strsplit(event->bymonth, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+
+               for (i = 0; t[i]; i++)
+               {
+                       int month = atoi(t[i]);
+                       ucal_set(ucal, UCAL_MONTH, month -1);
+
+                       if (event->byday && strlen(event->byday) > 0)
+                       {
+                               __cal_db_instance_publish_with_wday(ucal, event, duration, UCAL_YEAR, until);
+                       }
+                       else if (event->bymonthday && strlen(event->bymonthday) > 0)
+                       {
+                               __cal_db_instance_publish_with_mday(ucal, event, duration, UCAL_YEAR, until);
+                       }
+                       else
+                       {
+                               ERR("Not completed");
+                       }
+               }
+               g_strfreev(t);
+       }
+       else if (event->byyearday && strlen(event->byyearday) > 0)
+       {
+               __cal_db_instance_publish_with_yday(ucal, event, duration, UCAL_YEAR, until);
+
+       }
+       else if (event->byweekno && strlen(event->byweekno) > 0)
+       {
+               __cal_db_instance_publish_with_weekno(ucal, event, duration, UCAL_YEAR, until);
+
+               // range: 1 ~ 53 or -53 ~ -1 ex> 1, 4
+               t = g_strsplit(event->byweekno, d, -1);
+               if (!t) {
+                       ERR("g_strsplit failed");
+                       return CALENDAR_ERROR_OUT_OF_MEMORY;
+               }
+
+               for (i = 0; t[i]; i++)
+               {
+
+               }
+
+               g_strfreev(t);
+       }
+       else
+       {
+               UErrorCode ec = U_ZERO_ERROR;
+               int month = ucal_get(ucal, UCAL_MONTH, &ec) + 1;
+               DBG("No bymonth, so set start time month(%d)", month);
+
+               if (event->byday && strlen(event->byday) > 0)
+               {
+                       __cal_db_instance_publish_with_wday(ucal, event, duration, UCAL_YEAR, until);
+               }
+               else if (event->bymonthday && strlen(event->bymonthday) > 0)
+               {
+                       __cal_db_instance_publish_with_mday(ucal, event, duration, UCAL_YEAR, until);
+               }
+               else
+               {
+                       ERR("Not completed");
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_record_monthly(UCalendar *ucal, cal_event_s *event, int duration, calendar_time_s *until)
+{
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == event)
+       {
+               ERR("Invalid parameter: event is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       __cal_db_instance_set_ucal_start(ucal, &event->start);
+       __cal_db_instance_print_ucal(ucal);
+
+       if (event->byday && strlen(event->byday) > 0)
+       {
+               __cal_db_instance_publish_with_wday(ucal, event, duration, UCAL_MONTH, until);
+       }
+       else
+       {
+               // bymonthday or none
+               __cal_db_instance_publish_with_mday(ucal, event, duration, UCAL_MONTH, until);
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_record_weekly(UCalendar *ucal, cal_event_s *event, int duration, calendar_time_s *until)
+{
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == event)
+       {
+               ERR("Invalid parameter: event is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       __cal_db_instance_set_ucal_start(ucal, &event->start);
+       __cal_db_instance_publish_with_wday(ucal, event, duration, UCAL_WEEK_OF_YEAR, until);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_record_daily(UCalendar *ucal, cal_event_s *event, int duration, calendar_time_s *until)
+{
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == event)
+       {
+               ERR("Invalid parameter: event is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       __cal_db_instance_set_ucal_start(ucal, &event->start);
+       __cal_db_instance_print_ucal(ucal);
+
+       __cal_db_instance_publish_with_mday(ucal, event, duration, UCAL_DATE, until);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_record_once(UCalendar *ucal, cal_event_s *event, int duration, calendar_time_s *until)
+{
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == event)
+       {
+               ERR("Invalid parameter: event is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       __cal_db_instance_set_ucal_start(ucal, &event->start);
+       __cal_db_instance_print_ucal(ucal);
+
+       event->interval = 1;
+       event->count = 1;
+       event->range_type = CALENDAR_RANGE_COUNT;
+
+       // start:for exception record which has original_event_id, mod freq 0
+
+       __cal_db_instance_publish_with_mday(ucal, event, duration, UCAL_DATE, until);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_publish_record_details(UCalendar *ucal, cal_event_s *event)
+{
+       if (NULL == ucal)
+       {
+               ERR("Invalid parameter: ucal is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+       if (NULL == event)
+       {
+               ERR("Invalid parameter: event is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+
+       int duration = -1;
+       long long int range = 0;
+       calendar_time_s until = {0};
+
+       __cal_db_instance_get_duration(ucal, &event->start, &event->end, &duration);
+
+       switch (event->range_type)
+       {
+       case CALENDAR_RANGE_COUNT:
+               DBG("range count");
+               break;
+
+       case CALENDAR_RANGE_UNTIL:
+               DBG("range until");
+               until.type = event->until_type;
+               switch (until.type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       range = _cal_time_convert_itol(NULL, CAL_ENDLESS_LIMIT_YEAR,
+                                       CAL_ENDLESS_LIMIT_MONTH, CAL_ENDLESS_LIMIT_MDAY,
+                                       0, 0, 0);
+                       if (event->until_utime > range)
+                       {
+                               DBG("until time(%lld) > max, so set max(%lld)", event->until_utime, range);
+                               until.time.utime = range;
+                       }
+                       else
+                       {
+                               until.time.utime = event->until_utime;
+                       }
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       until.time.date.year = event->until_year;
+                       until.time.date.month = event->until_month;
+                       until.time.date.mday = event->until_mday;
+                       break;
+               }
+               break;
+
+       case CALENDAR_RANGE_NONE:
+               DBG("range none");
+               until.type = event->until_type;
+               switch (until.type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       until.time.utime = _cal_time_convert_itol(event->start_tzid,
+                                       CAL_ENDLESS_LIMIT_YEAR,
+                                       CAL_ENDLESS_LIMIT_MONTH,
+                                       CAL_ENDLESS_LIMIT_MDAY,
+                                       0, 0, 0);
+                       break;
+               case CALENDAR_TIME_LOCALTIME:
+                       until.time.date.year = CAL_ENDLESS_LIMIT_YEAR;
+                       until.time.date.month = CAL_ENDLESS_LIMIT_MONTH;
+                       until.time.date.mday = CAL_ENDLESS_LIMIT_MDAY;
+                       break;
+               }
+               break;
+       }
+
+       switch (event->freq)
+       {
+       case CALENDAR_RECURRENCE_YEARLY:
+               __cal_db_instance_publish_record_yearly(ucal, event, duration, &until);
+               break;
+
+       case CALENDAR_RECURRENCE_MONTHLY:
+               __cal_db_instance_publish_record_monthly(ucal, event, duration, &until);
+               break;
+
+       case CALENDAR_RECURRENCE_WEEKLY:
+               __cal_db_instance_publish_record_weekly(ucal, event, duration, &until);
+               break;
+
+       case CALENDAR_RECURRENCE_DAILY:
+               __cal_db_instance_publish_record_daily(ucal, event, duration, &until);
+               break;
+
+       case CALENDAR_RECURRENCE_NONE:
+       default:
+               __cal_db_instance_publish_record_once(ucal, event, duration, &until);
+               break;
+
+       }
+
+       if (event->bysetpos)
+       {
+               __cal_db_instance_apply_setpos(event->index, &event->start, event, event->freq);
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_instance_publish_record(calendar_record_h record)
+{
+       cal_event_s *event;
+
+       if (NULL == record)
+       {
+               ERR("Invalid argument: record is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       event = (cal_event_s *)(record);
+
+       DBG("Start");
+       __cal_db_instance_print_caltime(&event->start);
+       DBG("End");
+       __cal_db_instance_print_caltime(&event->end);
+
+
+       UCalendar *ucal = NULL;
+       switch (event->start.type)
+       {
+       case CALENDAR_TIME_UTIME:
+               ucal = _cal_time_get_ucal(event->start_tzid, event->wkst);
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               ucal = _cal_time_get_ucal(NULL, event->wkst);
+               break;
+       }
+
+       __cal_db_instance_publish_record_details(ucal, event);
+       __cal_db_instance_del_inundant(event->index, &event->start, event);
+       __cal_db_instance_update_exdate_del(event->index, event->exdate);
+       __cal_db_instance_update_exdate_mod(event->original_event_id, event->recurrence_id);
+
+       ucal_close(ucal);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_instance_get_now(long long int *current)
+{
+       *current = ms2sec(ucal_getNow());
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_instance_discard_record(calendar_record_h record)
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       cal_event_s *event;
+
+       event = (cal_event_s *)(record);
+       if (event == NULL) {
+               ERR("Invalid argument: cal_event_s is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       DBG("delete normal");
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE event_id = %d ",
+                       CAL_TABLE_NORMAL_INSTANCE, event->index);
+
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       DBG("delete allday");
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE event_id = %d ",
+                       CAL_TABLE_ALLDAY_INSTANCE, event->index);
+
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
diff --git a/native/cal_db_instance.h b/native/cal_db_instance.h
new file mode 100644 (file)
index 0000000..bd337c0
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_INSTANCE_H__
+#define __CALENDAR_SVC_DB_INSTANCE_H__
+
+int _cal_db_instance_publish_record(calendar_record_h record);
+int _cal_db_instance_discard_record(calendar_record_h record);;
+int _cal_db_instance_get_now(long long int *current);
+
+#endif // __CALENDAR_SVC_DB_INSTANCE_H__
diff --git a/native/cal_db_plugin_calendar.c b/native/cal_db_plugin_calendar.c
new file mode 100644 (file)
index 0000000..7f05798
--- /dev/null
@@ -0,0 +1,1125 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db.h"
+#include "cal_db_util.h"
+#include "cal_db_query.h"
+
+#ifdef CAL_IPC_SERVER
+#include "cal_server_calendar_delete.h"
+#endif
+
+/*
+ * db plugin function
+ */
+static int __cal_db_calendar_insert_record( calendar_record_h record, int* id );
+static int __cal_db_calendar_get_record( int id, calendar_record_h* out_record );
+static int __cal_db_calendar_update_record( calendar_record_h record );
+static int __cal_db_calendar_delete_record( int id );
+static int __cal_db_calendar_get_all_records( int offset, int limit, calendar_list_h* out_list );
+static int __cal_db_calendar_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list );
+static int __cal_db_calendar_insert_records(const calendar_list_h list, int** ids);
+static int __cal_db_calendar_update_records(const calendar_list_h list);
+static int __cal_db_calendar_delete_records(int ids[], int count);
+static int __cal_db_calendar_get_count(int *out_count);
+static int __cal_db_calendar_get_count_with_query(calendar_query_h query, int *out_count);
+static int __cal_db_calendar_replace_record(calendar_record_h record, int id);
+static int __cal_db_calendar_replace_records(const calendar_list_h list, int ids[], int count);
+
+/*
+ * static function
+ */
+static void __cal_db_calendar_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static void __cal_db_calendar_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int stmt_count, calendar_record_h record);
+static void __cal_db_calendar_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+static int __cal_db_calendar_update_projection(calendar_record_h record);
+
+cal_db_plugin_cb_s _cal_db_calendar_plugin_cb = {
+       .is_query_only=false,
+       .insert_record=__cal_db_calendar_insert_record,
+       .get_record=__cal_db_calendar_get_record,
+       .update_record=__cal_db_calendar_update_record,
+       .delete_record=__cal_db_calendar_delete_record,
+       .get_all_records=__cal_db_calendar_get_all_records,
+       .get_records_with_query=__cal_db_calendar_get_records_with_query,
+       .insert_records=__cal_db_calendar_insert_records,
+       .update_records=__cal_db_calendar_update_records,
+       .delete_records=__cal_db_calendar_delete_records,
+    .get_count=__cal_db_calendar_get_count,
+    .get_count_with_query=__cal_db_calendar_get_count_with_query,
+    .replace_record = __cal_db_calendar_replace_record,
+    .replace_records = __cal_db_calendar_replace_records
+};
+
+static int __cal_db_calendar_insert_record( calendar_record_h record, int* id )
+{
+       char query[CAL_DB_SQL_MAX_LEN];
+       int index = 0;
+       sqlite3_stmt *stmt;
+       cal_calendar_s* calendar =  (cal_calendar_s*)(record);
+       cal_db_util_error_e dbret = CAL_DB_OK;
+
+       // !! error check
+       retv_if(NULL == calendar, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       sprintf(query,"INSERT INTO %s(uid,updated,name,description,"
+                       "color,location,"
+                       "visibility,"
+                       "sync_event,"
+                       "account_id,store_type,sync_data1,sync_data2,sync_data3,sync_data4) "
+                       "VALUES( ?, %ld, ?, ?, ?, ?, %d, %d, %d, %d"
+                       ", ?, ?, ?, ?)",
+                       CAL_TABLE_CALENDAR,
+                       //calendar->uid,
+                       calendar->updated,
+                       //calendar->name,
+                       //calendar->description,
+                       //calendar->color,
+                       //calendar->location,
+                       calendar->visibility,
+                       calendar->sync_event,
+                       calendar->account_id,
+                       calendar->store_type);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       if (calendar->uid)
+               _cal_db_util_stmt_bind_text(stmt, 1, calendar->uid);
+
+       if (calendar->name)
+               _cal_db_util_stmt_bind_text(stmt, 2, calendar->name);
+
+       if (calendar->description)
+               _cal_db_util_stmt_bind_text(stmt, 3, calendar->description);
+
+       if (calendar->color)
+               _cal_db_util_stmt_bind_text(stmt, 4, calendar->color);
+
+       if (calendar->location)
+               _cal_db_util_stmt_bind_text(stmt, 5, calendar->location);
+
+       // sync1~4
+       if (calendar->sync_data1)
+               _cal_db_util_stmt_bind_text(stmt, 6, calendar->sync_data1 );
+       if (calendar->sync_data2)
+               _cal_db_util_stmt_bind_text(stmt, 7, calendar->sync_data2 );
+       if (calendar->sync_data3)
+               _cal_db_util_stmt_bind_text(stmt, 8, calendar->sync_data3 );
+       if (calendar->sync_data4)
+               _cal_db_util_stmt_bind_text(stmt, 9, calendar->sync_data4 );
+
+       dbret = _cal_db_util_stmt_step(stmt);
+
+       if (CAL_DB_DONE != dbret) {
+               sqlite3_finalize(stmt);
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       index = _cal_db_util_last_insert_id();
+       sqlite3_finalize(stmt);
+
+       //_cal_record_set_int(record, _calendar_book.id,index);
+       if (id)
+       {
+           *id = index;
+       }
+
+       _cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_get_record( int id, calendar_record_h* out_record )
+{
+       cal_calendar_s *calendar=NULL;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       int ret = 0;
+
+       ret = calendar_record_create( _calendar_book._uri ,out_record);
+       if (ret != CALENDAR_ERROR_NONE)
+       {
+           ERR("record create fail");
+           return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       calendar = (cal_calendar_s*)(*out_record);
+
+       snprintf(query, sizeof(query), "SELECT * FROM %s WHERE id=%d "
+               "AND (deleted = 0)",
+                       CAL_TABLE_CALENDAR,     id);
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (dbret != CAL_DB_ROW) {
+               ERR("Failed to step stmt(%d)", dbret);
+               sqlite3_finalize(stmt);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       __cal_db_calendar_get_stmt(stmt, *out_record);
+
+       sqlite3_finalize(stmt);
+       stmt = NULL;
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_update_record( calendar_record_h record )
+{
+       //int rc = -1;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       sqlite3_stmt *stmt = NULL;
+       cal_calendar_s* calendar =  (cal_calendar_s*)(record);
+       cal_db_util_error_e dbret = CAL_DB_OK;
+
+       retv_if(NULL == calendar, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       if (calendar->common.properties_flags != NULL)
+       {
+           return __cal_db_calendar_update_projection(record);
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET "
+                       "updated = %ld,"
+                       "name = ?,"
+                       "description = ?,"
+                       "color = ?,"
+                       "location = ?,"
+                       "visibility = %d,"
+                       "sync_event = %d,"
+                       "account_id = %d,"
+                       "store_type = %d, "
+               "sync_data1 = ?, "
+               "sync_data2 = ?, "
+               "sync_data3 = ?, "
+               "sync_data4 = ? "
+                       "WHERE id = %d",
+               CAL_TABLE_CALENDAR,
+               calendar->updated,
+               calendar->visibility,
+               calendar->sync_event,
+               calendar->account_id,
+               calendar->store_type,
+               calendar->index);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       if (calendar->name)
+               _cal_db_util_stmt_bind_text(stmt, 1, calendar->name);
+
+       if (calendar->description)
+               _cal_db_util_stmt_bind_text(stmt, 2, calendar->description);
+
+       if (calendar->color)
+               _cal_db_util_stmt_bind_text(stmt, 3, calendar->color);
+
+       if (calendar->location)
+               _cal_db_util_stmt_bind_text(stmt, 4, calendar->location);
+
+       // sync_data1~4
+    if (calendar->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, 5, calendar->sync_data1);
+    if (calendar->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, 6, calendar->sync_data2);
+    if (calendar->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, 7, calendar->sync_data3);
+    if (calendar->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, 8, calendar->sync_data4);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_DONE != dbret) {
+               sqlite3_finalize(stmt);
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       sqlite3_finalize(stmt);
+
+       _cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_delete_record( int id )
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       cal_db_util_error_e dbret = CAL_DB_OK;
+
+#ifdef CAL_IPC_SERVER
+       int ret;
+       int count = 0;
+       int count2 = 0;
+       // get instance count
+    snprintf(query, sizeof(query), "select count(*) from %s",
+            CAL_TABLE_NORMAL_INSTANCE);
+       ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+
+    snprintf(query, sizeof(query), "select count(*) from %s",
+            CAL_TABLE_ALLDAY_INSTANCE);
+    ret = _cal_db_util_query_get_first_int_result(query,NULL, &count2);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+
+       count += count2;
+
+    if( count > 1000 )
+    {
+        snprintf(query, sizeof(query), "UPDATE %s SET deleted = 1 WHERE id = %d",
+                CAL_TABLE_CALENDAR, id);
+        dbret = _cal_db_util_query_exec(query);
+        if (CAL_DB_OK != dbret)
+        {
+            ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+        }
+        _cal_server_calendar_delete_start();
+    }
+    else
+    {
+#endif
+        snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d",
+                CAL_TABLE_CALENDAR, id);
+        dbret = _cal_db_util_query_exec(query);
+        if (CAL_DB_OK != dbret)
+        {
+            ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+        }
+
+        snprintf(query, sizeof(query), "DELETE FROM %s WHERE calendar_id = %d",
+                CAL_TABLE_SCHEDULE, id);
+        dbret = _cal_db_util_query_exec(query);
+        if (CAL_DB_OK != dbret) {
+            ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+        }
+#ifdef CAL_IPC_SERVER
+    }
+#endif
+
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE calendar_id = %d",
+                       CAL_TABLE_DELETED, id);
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret) {
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       _cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_replace_record(calendar_record_h record, int id)
+{
+       //int rc = -1;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       sqlite3_stmt *stmt = NULL;
+       cal_calendar_s* calendar =  (cal_calendar_s*)(record);
+       cal_db_util_error_e dbret = CAL_DB_OK;
+
+       retv_if(NULL == calendar, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       if (calendar->common.properties_flags != NULL)
+       {
+           return __cal_db_calendar_update_projection(record);
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET "
+                       "updated = %ld,"
+                       "name = ?,"
+                       "description = ?,"
+                       "color = ?,"
+                       "location = ?,"
+                       "visibility = %d,"
+                       "sync_event = %d,"
+                       "account_id = %d,"
+                       "store_type = %d, "
+               "sync_data1 = ?, "
+               "sync_data2 = ?, "
+               "sync_data3 = ?, "
+               "sync_data4 = ? "
+                       "WHERE id = %d",
+               CAL_TABLE_CALENDAR,
+               calendar->updated,
+               calendar->visibility,
+               calendar->sync_event,
+               calendar->account_id,
+               calendar->store_type,
+               id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       if (calendar->name)
+               _cal_db_util_stmt_bind_text(stmt, 1, calendar->name);
+
+       if (calendar->description)
+               _cal_db_util_stmt_bind_text(stmt, 2, calendar->description);
+
+       if (calendar->color)
+               _cal_db_util_stmt_bind_text(stmt, 3, calendar->color);
+
+       if (calendar->location)
+               _cal_db_util_stmt_bind_text(stmt, 4, calendar->location);
+
+       // sync_data1~4
+    if (calendar->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, 5, calendar->sync_data1);
+    if (calendar->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, 6, calendar->sync_data2);
+    if (calendar->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, 7, calendar->sync_data3);
+    if (calendar->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, 8, calendar->sync_data4);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_DONE != dbret) {
+               sqlite3_finalize(stmt);
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       sqlite3_finalize(stmt);
+
+       _cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
+       return CALENDAR_ERROR_NONE;
+}
+
+
+static int __cal_db_calendar_get_all_records( int offset, int limit, calendar_list_h* out_list )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query), "SELECT * FROM %s %s %s where deleted = 0",
+            CAL_TABLE_CALENDAR,limitquery,offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+               *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_book._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_calendar_get_stmt(stmt,record);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    sqlite3_finalize(stmt);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list )
+{
+    cal_query_s *que = NULL;
+    int i = 0;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+
+    que = (cal_query_s *)query;
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, CAL_TABLE_CALENDAR);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", CAL_TABLE_CALENDAR);
+    }
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE (%s) AND (deleted = 0)", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_book._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_calendar_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_calendar_get_stmt(stmt,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+    sqlite3_finalize(stmt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_insert_records(const calendar_list_h list, int** ids)
+{
+    calendar_record_h record;
+    int ret = 0;
+    int count = 0;
+    int i=0;
+    int *id = NULL;
+
+    ret = calendar_list_get_count(list, &count);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list get error");
+        return ret;
+    }
+
+    id = calloc(1, sizeof(int)*count);
+
+    retvm_if(NULL == id, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc fail");
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        CAL_FREE(id);
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_calendar_insert_record(record, &id[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                CAL_FREE(id);
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+        i++;
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    if(ids)
+    {
+        *ids = id;
+    }
+    else
+    {
+        CAL_FREE(id);
+    }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_update_records(const calendar_list_h list)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_calendar_update_record(record) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_delete_records(int ids[], int count)
+{
+    int i=0;
+    for(i=0;i<count;i++)
+    {
+        if (__cal_db_calendar_delete_record(ids[i]) != CALENDAR_ERROR_NONE)
+        {
+            ERR("delete failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+    }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_replace_records(const calendar_list_h list, int ids[], int count)
+{
+    calendar_record_h record;
+       int i = 0;
+    int ret = 0;
+
+       if (NULL == list)
+       {
+               ERR("Invalid argument: list is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+
+       for (i = 0; i < count; i++)
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_calendar_replace_record(record, ids[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+               if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
+               {
+                       break;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s where deleted = 0", CAL_TABLE_CALENDAR);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_calendar_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_TABLE_CALENDAR);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE (%s) AND (deleted = 0)", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    if (out_count) *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_calendar_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
+{
+    cal_calendar_s* calendar =  (cal_calendar_s*)(record);
+    int count = 0;
+    const unsigned char *temp;
+
+    calendar->index = sqlite3_column_int(stmt, count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->uid = SAFE_STRDUP(temp);
+
+    calendar->updated = sqlite3_column_int(stmt, count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->name = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->description = SAFE_STRDUP(temp);
+
+
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->color = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->location = SAFE_STRDUP(temp);
+
+    calendar->visibility = sqlite3_column_int(stmt, count++);
+    calendar->sync_event = sqlite3_column_int(stmt, count++);
+    calendar->is_deleted = sqlite3_column_int(stmt, count++);
+    calendar->account_id = sqlite3_column_int(stmt, count++);
+    calendar->store_type = sqlite3_column_int(stmt, count++);
+
+    //sync_data1~4
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->sync_data1 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->sync_data2 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->sync_data3 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    calendar->sync_data4 = SAFE_STRDUP(temp);
+
+    //deleted
+    sqlite3_column_int(stmt, count++);
+}
+
+static void __cal_db_calendar_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int stmt_count, calendar_record_h record)
+{
+    cal_calendar_s* calendar =  (cal_calendar_s*)(record);
+    const unsigned char *temp;
+
+    switch(property)
+    {
+    case CAL_PROPERTY_CALENDAR_ID:
+        calendar->index = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_CALENDAR_UID:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->uid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_CALENDAR_NAME:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->name = SAFE_STRDUP(temp);
+        CAL_DBG("calendar->name=%s",calendar->name);
+        break;
+    case CAL_PROPERTY_CALENDAR_DESCRIPTION:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->description = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_CALENDAR_COLOR:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->color = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_CALENDAR_LOCATION:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->location = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_CALENDAR_VISIBILITY:
+        calendar->visibility = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_CALENDAR_SYNC_EVENT:
+        calendar->sync_event = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_CALENDAR_IS_DELETED:
+        calendar->is_deleted = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_CALENDAR_ACCOUNT_ID:
+        calendar->account_id = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_CALENDAR_STORE_TYPE:
+        calendar->store_type = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_CALENDAR_SYNC_DATA1:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->sync_data1 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_CALENDAR_SYNC_DATA2:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->sync_data1 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_CALENDAR_SYNC_DATA3:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->sync_data1 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_CALENDAR_SYNC_DATA4:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        calendar->sync_data1 = SAFE_STRDUP(temp);
+        break;
+    default:
+        sqlite3_column_int(stmt, stmt_count);
+        break;
+    }
+
+    return;
+}
+
+static void __cal_db_calendar_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_calendar_get_property_stmt(stmt,projection[i],i,record);
+    }
+}
+
+static int __cal_db_calendar_update_projection(calendar_record_h record)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_calendar_s* calendar =  (cal_calendar_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int ret = CALENDAR_ERROR_NONE;
+    char* set = NULL;
+    GSList *bind_text = NULL;
+    int len;
+    GSList *cursor = NULL;
+
+    ret = _cal_db_query_create_projection_update_set(record,&set,&bind_text);
+    retv_if(CALENDAR_ERROR_NONE != ret, ret);
+
+    snprintf(query, sizeof(query), "UPDATE %s SET %s "
+            "WHERE id = %d",
+            CAL_TABLE_CALENDAR,set,
+            calendar->index);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    // bind
+    if (bind_text)
+    {
+        int i = 0;
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret) {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+
+        CAL_FREE(set);
+        if(bind_text)
+        {
+            for (cursor=bind_text; cursor;cursor=cursor->next)
+            {
+                CAL_FREE(cursor->data);
+            }
+            g_slist_free(bind_text);
+        }
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    sqlite3_finalize(stmt);
+
+    _cal_db_util_notify(CAL_NOTI_TYPE_CALENDAR);
+
+    CAL_FREE(set);
+    if(bind_text)
+    {
+        for (cursor=bind_text; cursor;cursor=cursor->next)
+        {
+            CAL_FREE(cursor->data);
+        }
+        g_slist_free(bind_text);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/native/cal_db_plugin_event.c b/native/cal_db_plugin_event.c
new file mode 100644 (file)
index 0000000..bf4f071
--- /dev/null
@@ -0,0 +1,2645 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "calendar_db.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_time.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_rrule.h"
+#include "cal_db_query.h"
+#include "cal_db_alarm.h"
+#include "cal_db_instance.h"
+#include "cal_db_attendee.h"
+#include "cal_db_extended.h"
+
+static int __cal_db_event_insert_record(calendar_record_h record, int* id);
+static int __cal_db_event_get_record(int id, calendar_record_h* out_record);
+static int __cal_db_event_update_record(calendar_record_h record);
+static int __cal_db_event_delete_record(int id);
+static int __cal_db_event_get_all_records(int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_event_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_event_insert_records(const calendar_list_h list, int** ids);
+static int __cal_db_event_update_records(const calendar_list_h list);
+static int __cal_db_event_delete_records(int ids[], int count);
+static int __cal_db_event_get_count(int *out_count);
+static int __cal_db_event_get_count_with_query(calendar_query_h query, int *out_count);
+static int __cal_db_event_replace_record(calendar_record_h record, int id);
+static int __cal_db_event_replace_records(const calendar_list_h list, int ids[], int count);
+/*
+ * static function
+ */
+static void __cal_db_event_get_stmt(sqlite3_stmt *stmt,bool is_view_table,calendar_record_h record);
+static void __cal_db_event_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record);
+static void __cal_db_event_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+static int __cal_db_event_update_dirty(calendar_record_h record);
+/*  // under construction
+bool __cal_db_event_check_changed_rrule(record);
+*/
+static int __cal_db_event_exception_get_records(int original_id, GList **out_list);
+static int __cal_db_event_exception_convert_gtoh(GList *glist, int original_id, calendar_list_h *hlist);
+static int __cal_db_event_exception_delete_with_id(int original_id);
+
+cal_db_plugin_cb_s _cal_db_event_plugin_cb = {
+       .is_query_only = false,
+       .insert_record = __cal_db_event_insert_record,
+       .get_record = __cal_db_event_get_record,
+       .update_record = __cal_db_event_update_record,
+       .delete_record = __cal_db_event_delete_record,
+       .get_all_records = __cal_db_event_get_all_records,
+       .get_records_with_query = __cal_db_event_get_records_with_query,
+       .insert_records = __cal_db_event_insert_records,
+       .update_records = __cal_db_event_update_records,
+       .delete_records = __cal_db_event_delete_records,
+    .get_count = __cal_db_event_get_count,
+    .get_count_with_query = __cal_db_event_get_count_with_query,
+    .replace_record = __cal_db_event_replace_record,
+    .replace_records = __cal_db_event_replace_records
+};
+
+static int __cal_db_event_check_value_validation(cal_event_s *event)
+{
+       retv_if(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       if (event->start.type != event->end.type)
+       {
+               ERR("start type(%d) is not same as end type(%d)", event->start.type, event->end.type);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       long long int slli = 0;
+       long long int elli = 0;
+       switch (event->start.type)
+       {
+       case CALENDAR_TIME_UTIME:
+               if (event->start.time.utime > event->end.time.utime)
+               {
+                       ERR("normal start(%lld) > end(%lld)",
+                               event->start.time.utime, event->end.time.utime);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               break;
+
+       case CALENDAR_TIME_LOCALTIME:
+               // check invalid value
+               if (event->start.time.date.month < 1 || event->start.time.date.month > 12)
+               {
+                       ERR("check start month(input:%d)", event->start.time.date.month);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               else if (event->start.time.date.mday < 1 || event->start.time.date.mday > 31)
+               {
+                       ERR("check start mday(input:%d)", event->start.time.date.mday);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               else if (event->end.time.date.month < 1 || event->end.time.date.month > 12)
+               {
+                       ERR("check end month(input:%d)", event->end.time.date.month);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               else if (event->end.time.date.mday < 1 || event->end.time.date.mday > 31)
+               {
+                       ERR("check end mday(input:%d)", event->end.time.date.mday);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+
+               // check start > end
+               slli = _cal_time_convert_itol(NULL, event->start.time.date.year,
+                               event->start.time.date.month, event->start.time.date.mday, 0, 0, 0);
+               elli = _cal_time_convert_itol(NULL, event->end.time.date.year,
+                               event->end.time.date.month, event->end.time.date.mday, 0, 0, 0);
+
+               if (slli > elli)
+               {
+                       ERR("allday start(%lld) > end(%lld)", slli, elli);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               break;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_insert_record(calendar_record_h record, int* id)
+{
+       int ret = -1;
+       int event_id = -1;
+       int index;
+       int input_ver;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char dtstart_datetime[32] = {0};
+       char dtend_datetime[32] = {0};
+       sqlite3_stmt *stmt = NULL;
+       cal_event_s* event =  (cal_event_s*)(record);
+       cal_rrule_s *rrule = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       int tmp = 0;
+       int calendar_book_id = 0;
+       calendar_record_h record_calendar = NULL;
+       int has_alarm = 0;
+       int timezone_id = 0;
+
+       retv_if(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       ret = __cal_db_event_check_value_validation(event);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("__cal_db_event_check_value_validation() failed");
+               return ret;
+       }
+
+    ret = calendar_record_get_int(record, _calendar_event.calendar_book_id, &calendar_book_id);
+    DBG("calendar_book_id(%d)", calendar_book_id);
+
+    ret = calendar_db_get_record(_calendar_book._uri, calendar_book_id, &record_calendar);
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "calendar_book_id is invalid");
+
+    calendar_record_destroy(record_calendar, true);
+
+    has_alarm = _cal_db_alarm_has_alarm(event->alarm_list);
+       _cal_time_get_timezone_from_table(event->start_tzid, NULL, &timezone_id);
+       input_ver = _cal_db_util_get_next_ver();
+       ret = snprintf(query, sizeof(query),
+               "INSERT INTO %s ("
+                       "type, "
+                       "created_ver, changed_ver, "
+                       "summary, description, location, categories, exdate, "
+                       "task_status, priority, "
+                       "timezone, "
+                       "contact_id, busy_status, sensitivity, uid, "
+                       "organizer_name, organizer_email, meeting_status, "
+                       "calendar_id, "
+                       "original_event_id, "
+                       "latitude, longitude, "
+                       "email_id, availability, "
+                       "created_time, completed_time, progress, "
+                       "dtstart_type, dtstart_utime, dtstart_datetime, dtstart_tzid, "
+                       "dtend_type, dtend_utime, dtend_datetime, dtend_tzid, "
+                       "last_mod, rrule_id, "
+               "recurrence_id, rdate, has_attendee, "
+               "has_alarm, system_type, updated, "
+               "sync_data1, sync_data2, sync_data3, sync_data4 "
+                       ") VALUES ( "
+                       "%d, "
+                       "%d, %d, "
+                       "?, ?, ?, ?, ?, "
+                       "%d, %d, "
+                       "%d, "
+                       "%d, %d, %d, ?, "
+                       "?, ?, %d, "
+                       "%d, "
+                       "%d, "
+                       "%lf, %lf, "
+                       "%d, %d, "
+                       "strftime('%%s', 'now'), %lld, %d, "
+                       "%d, %lld, ?, ?, "
+                       "%d, %lld, ?, ?, "
+                       "strftime('%%s', 'now'), %d "
+               ", ?, ?, %d, %d, %d, %ld"
+               ", ?, ?, ?, ?"
+                       ") ",
+                       CAL_TABLE_SCHEDULE,
+                       CAL_SCH_TYPE_EVENT, /*event->cal_type,*/
+                       input_ver, input_ver,
+                       event->event_status, event->priority,
+                       event->timezone ? event->timezone : timezone_id,
+                       event->contact_id, event->busy_status, event->sensitivity,
+                       event->meeting_status,
+                       event->calendar_id,
+                       event->original_event_id,
+                       event->latitude, event->longitude,
+                       event->email_id, 0,//event->availability,
+                       (long long int)0, 0, //event->completed_time, event->progress,
+                       event->start.type, event->start.type == CALENDAR_TIME_UTIME ? event->start.time.utime : 0,
+                       event->end.type, event->end.type == CALENDAR_TIME_UTIME ? event->end.time.utime : 0,
+                       event->freq > 0 ? 1 : 0,
+                       event->attendee_list ? 1 : 0,
+                       has_alarm,
+                       event->system_type,
+                       event->updated);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED,
+                       "_cal_db_util_query_prepare() Failed");
+
+       index = 1;
+
+       if (event->summary)
+               _cal_db_util_stmt_bind_text(stmt, index, event->summary);
+       index++;
+
+       if (event->description)
+               _cal_db_util_stmt_bind_text(stmt, index, event->description);
+       index++;
+
+       if (event->location)
+               _cal_db_util_stmt_bind_text(stmt, index, event->location);
+       index++;
+
+       if (event->categories)
+               _cal_db_util_stmt_bind_text(stmt, index, event->categories);
+       index++;
+
+       if (event->exdate)
+               _cal_db_util_stmt_bind_text(stmt, index, event->exdate);
+       index++;
+
+       if (event->uid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->uid);
+       index++;
+
+       if (event->organizer_name)
+               _cal_db_util_stmt_bind_text(stmt, index, event->organizer_name);
+       index++;
+
+       if (event->organizer_email)
+               _cal_db_util_stmt_bind_text(stmt, index, event->organizer_email);
+       index++;
+
+       if (CALENDAR_TIME_LOCALTIME == event->start.type)
+       {
+               snprintf(dtstart_datetime, sizeof(dtstart_datetime), "%04d%02d%02d",
+                               event->start.time.date.year,
+                               event->start.time.date.month,
+                               event->start.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, index, dtstart_datetime);
+       }
+       index++;
+
+       if (event->start_tzid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->start_tzid);
+       index++;
+
+       if (CALENDAR_TIME_LOCALTIME == event->end.type)
+       {
+               snprintf(dtend_datetime, sizeof(dtend_datetime), "%04d%02d%02d",
+                               event->end.time.date.year,
+                               event->end.time.date.month,
+                               event->end.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, index, dtend_datetime);
+       }
+       index++;
+
+       if (event->end_tzid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->end_tzid);
+       index++;
+
+    if (event->recurrence_id)
+        _cal_db_util_stmt_bind_text(stmt, index, event->recurrence_id);
+       index++;
+
+    if (event->rdate)
+        _cal_db_util_stmt_bind_text(stmt, index, event->rdate);
+       index++;
+
+    if (event->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data1);
+       index++;
+
+    if (event->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data2);
+       index++;
+
+    if (event->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data3);
+       index++;
+
+    if (event->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data4);
+       index++;
+
+    dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_DONE != dbret)
+       {
+               sqlite3_finalize(stmt);
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+       event_id = _cal_db_util_last_insert_id();
+       sqlite3_finalize(stmt);
+
+       calendar_record_get_int(record, _calendar_event.id, &tmp);
+       _cal_record_set_int(record, _calendar_event.id, event_id);
+       if (id)
+    {
+        *id = event_id;
+    }
+
+       _cal_db_rrule_set_default(record);
+       _cal_db_rrule_get_rrule_from_event(record, &rrule);
+       _cal_db_rrule_insert_record(event_id, rrule);
+       _cal_db_instance_publish_record(record);
+
+       calendar_list_h list;
+       if (event->alarm_list)
+       {
+               list = NULL;
+               DBG("insert alarm");
+               ret = _cal_db_alarm_convert_gtoh(event->alarm_list, event_id, &list);
+               ret = calendar_db_insert_records(list, NULL, NULL);
+               ret = calendar_list_destroy(list, false);
+       }
+       else
+       {
+               DBG("No alarm");
+       }
+
+       if (event->attendee_list)
+       {
+               list = NULL;
+               DBG("insert attendee");
+               ret = _cal_db_attendee_convert_gtoh(event->attendee_list, event_id, &list);
+               ret = calendar_db_insert_records(list, NULL, NULL);
+               ret = calendar_list_destroy(list, false);
+       }
+       else
+       {
+               DBG("No attendee");
+       }
+
+       if (event->exception_list)
+       {
+           DBG("insert exception");
+        list = NULL;
+        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, event_id, &list);
+        ret = calendar_db_insert_records(list, NULL, NULL);
+        ret = calendar_list_destroy(list, false);
+       }
+    else
+    {
+        DBG("No exception");
+    }
+
+       if (event->extended_list)
+       {
+           DBG("insert extended");
+        list = NULL;
+        ret = _cal_db_extended_convert_gtoh(event->extended_list, event_id, CALENDAR_RECORD_TYPE_EVENT, &list);
+        ret = calendar_db_insert_records(list, NULL, NULL);
+        ret = calendar_list_destroy(list, false);
+       }
+    else
+    {
+        DBG("No extended");
+    }
+
+       CAL_FREE(rrule);
+       _cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
+
+       _cal_record_set_int(record, _calendar_event.id, tmp);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_get_record(int id, calendar_record_h* out_record)
+{
+       char query[CAL_DB_SQL_MAX_LEN];
+       int ret = 0;
+       sqlite3_stmt *stmt = NULL;
+       cal_event_s *event = NULL;
+       cal_rrule_s *rrule = NULL;
+       GList *alarm_list, *attendee_list;
+       GList *exception_list = NULL, *extended_list = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+
+       ret = calendar_record_create( _calendar_event._uri ,out_record);
+       if (ret != CALENDAR_ERROR_NONE)
+       {
+               ERR("calendar_record_create(%d)", ret);
+           return CALENDAR_ERROR_OUT_OF_MEMORY;
+       }
+
+       event = (cal_event_s*)(*out_record);
+
+       snprintf(query, sizeof(query),
+                       "SELECT * FROM %s "
+                       "WHERE id = %d AND type = %d AND calendar_id IN "
+                       "(select id from %s where deleted = 0)",
+                       CAL_TABLE_SCHEDULE,
+                       id, CALENDAR_BOOK_TYPE_EVENT,
+                       CAL_TABLE_CALENDAR);
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (dbret != CAL_DB_ROW)
+       {
+               ERR("query[%s]", query);
+               ERR("Failed to step stmt(%d)", dbret);
+               sqlite3_finalize(stmt);
+        calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+               switch (dbret)
+               {
+               case CAL_DB_DONE:
+                       ERR("Failed to find record(id:%d, ret:%d)", id, dbret);
+                       return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       __cal_db_event_get_stmt(stmt,false,*out_record);
+       sqlite3_finalize(stmt);
+       stmt = NULL;
+
+       if (_cal_db_rrule_get_rrule(event->index, &rrule) == CALENDAR_ERROR_NONE )
+       {
+           _cal_db_rrule_set_rrule_to_event(rrule, *out_record);
+           CAL_FREE(rrule);
+       }
+
+       _cal_db_alarm_get_records(event->index, &alarm_list);
+       event->alarm_list = alarm_list;
+
+       _cal_db_attendee_get_records(event->index, &attendee_list);
+       event->attendee_list = attendee_list;
+
+       __cal_db_event_exception_get_records(event->index, &exception_list);
+       event->exception_list = exception_list;
+
+       _cal_db_extended_get_records(event->index, CALENDAR_RECORD_TYPE_EVENT, &extended_list);
+    event->extended_list = extended_list;
+
+       event->has_alarm = 0;
+       if (event->alarm_list)
+       {
+        if (g_list_length(event->alarm_list) != 0)
+        {
+            event->has_alarm = 1;
+        }
+       }
+    event->has_attendee = 0;
+    if (event->attendee_list)
+    {
+        if (g_list_length(event->attendee_list) != 0)
+        {
+            event->has_attendee = 1;
+        }
+    }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_update_record(calendar_record_h record)
+{
+       int ret;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char dtstart_datetime[32] = {0};
+       char dtend_datetime[32] = {0};
+       sqlite3_stmt *stmt = NULL;
+       cal_event_s* event =  (cal_event_s*)(record);
+       cal_rrule_s *rrule = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       int has_alarm = 0;
+       int timezone_id = 0;
+
+       retv_if(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       ret = __cal_db_event_check_value_validation(event);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("__cal_db_event_check_value_validation() failed");
+               return ret;
+       }
+
+    if (event->common.properties_flags != NULL)
+    {
+        return __cal_db_event_update_dirty(record);
+    }
+    has_alarm = _cal_db_alarm_has_alarm(event->alarm_list);
+       _cal_time_get_timezone_from_table(event->start_tzid, NULL, &timezone_id);
+       snprintf(query, sizeof(query), "UPDATE %s SET "
+                       "changed_ver = %d,"
+                       "type = %d,"
+                       "summary = ?,"
+                       "description = ?,"
+                       "location = ?,"
+                       "categories = ?,"
+                       "exdate = ?,"
+                       "task_status = %d,"
+                       "priority = %d,"
+                       "timezone = %d, "
+                       "contact_id = %d, "
+                       "busy_status = %d, "
+                       "sensitivity = %d, "
+                       "uid = ?, "
+                       "organizer_name = ?, "
+                       "organizer_email = ?, "
+                       "meeting_status = %d, "
+                       "calendar_id = %d, "
+                       "original_event_id = %d,"
+                       "latitude = %lf,"
+                       "longitude = %lf,"
+                       "email_id = %d,"
+               "availability = %d,"
+                       "completed_time = %lld,"
+                       "progress = %d, "
+                       "dtstart_type = %d, "
+                       "dtstart_utime = %lld, "
+                       "dtstart_datetime = ?, "
+                       "dtstart_tzid = ?, "
+                       "dtend_type = %d, "
+                       "dtend_utime = %lld, "
+                       "dtend_datetime = ?, "
+                       "dtend_tzid = ?, "
+                       "last_mod = strftime('%%s', 'now'), "
+                       "rrule_id = %d, "
+               "recurrence_id = ?, "
+               "rdate = ?, "
+               "has_attendee = %d, "
+               "has_alarm = %d, "
+               "system_type = %d, "
+               "updated = %ld, "
+               "sync_data1 = ?, "
+               "sync_data2 = ?, "
+               "sync_data3 = ?, "
+               "sync_data4 = ? "
+                       "WHERE id = %d;",
+               CAL_TABLE_SCHEDULE,
+               _cal_db_util_get_next_ver(),
+               CAL_SCH_TYPE_EVENT,/*event->cal_type,*/
+               event->event_status,
+               event->priority,
+               event->timezone ? event->timezone : timezone_id,
+               event->contact_id,
+               event->busy_status,
+               event->sensitivity,
+               event->meeting_status,
+               event->calendar_id,
+               event->original_event_id,
+               event->latitude,
+               event->longitude,
+               event->email_id,
+               0,//event->availability,
+               (long long int)0,//event->completed_time,
+               0,//event->progress,
+               event->start.type,
+               event->start.type == CALENDAR_TIME_UTIME ? event->start.time.utime : 0,
+               event->end.type,
+               event->end.type == CALENDAR_TIME_UTIME ? event->end.time.utime : 0,
+               event->freq > 0 ? 1 : 0,
+               event->attendee_list ? 1: 0,
+               has_alarm,
+               event->system_type,
+               event->updated,
+               event->index);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       int index = 1;
+
+       if (event->summary)
+               _cal_db_util_stmt_bind_text(stmt, index, event->summary);
+       index++;
+
+       if (event->description)
+               _cal_db_util_stmt_bind_text(stmt, index, event->description);
+       index++;
+
+       if (event->location)
+               _cal_db_util_stmt_bind_text(stmt, index, event->location);
+       index++;
+
+       if (event->categories)
+               _cal_db_util_stmt_bind_text(stmt, index, event->categories);
+       index++;
+
+       if (event->exdate)
+               _cal_db_util_stmt_bind_text(stmt, index, event->exdate);
+       index++;
+
+       if (event->uid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->uid);
+       index++;
+
+       if (event->organizer_name)
+               _cal_db_util_stmt_bind_text(stmt, index, event->organizer_name);
+       index++;
+
+       if (event->organizer_email)
+               _cal_db_util_stmt_bind_text(stmt, index, event->organizer_email);
+       index++;
+
+       if (CALENDAR_TIME_LOCALTIME == event->start.type)
+       {
+               snprintf(dtstart_datetime, sizeof(dtstart_datetime), "%04d%02d%02d",
+                               event->start.time.date.year,
+                               event->start.time.date.month,
+                               event->start.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, index, dtstart_datetime);
+       }
+       index++;
+
+       if (event->start_tzid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->start_tzid);
+       index++;
+
+       if (CALENDAR_TIME_LOCALTIME == event->end.type)
+       {
+               snprintf(dtend_datetime, sizeof(dtend_datetime), "%04d%02d%02d",
+                               event->end.time.date.year,
+                               event->end.time.date.month,
+                               event->end.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, index, dtend_datetime);
+       }
+       index++;
+
+       if (event->end_tzid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->end_tzid);
+       index++;
+
+    if (event->recurrence_id)
+        _cal_db_util_stmt_bind_text(stmt, index, event->recurrence_id);
+    index++;
+    if (event->rdate)
+        _cal_db_util_stmt_bind_text(stmt, index, event->rdate);
+    index++;
+    if (event->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data1);
+    index++;
+    if (event->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data2);
+    index++;
+    if (event->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data3);
+    index++;
+    if (event->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data4);
+    index++;
+
+    dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_DONE != dbret) {
+               sqlite3_finalize(stmt);
+               ERR("sqlite3_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+       sqlite3_finalize(stmt);
+
+       _cal_db_rrule_get_rrule_from_event(record, &rrule);
+       _cal_db_rrule_update_record(event->index, rrule);
+       CAL_FREE(rrule);
+
+       ret = _cal_db_instance_discard_record(record);
+       retvm_if(ret != CALENDAR_ERROR_NONE, CALENDAR_ERROR_DB_FAILED,
+                       "_cal_db_instance_discard_record() Failed(%d)", ret);
+
+       _cal_db_instance_publish_record(record);
+
+       _cal_db_alarm_delete_with_id(event->index);
+       _cal_db_attendee_delete_with_id(event->index);
+       __cal_db_event_exception_delete_with_id(event->index);
+       _cal_db_extended_delete_with_id(event->index, CALENDAR_RECORD_TYPE_EVENT);
+
+       calendar_list_h list;
+
+       list = NULL;
+       ret = _cal_db_alarm_convert_gtoh(event->alarm_list,event->index, &list);
+       if (ret == CALENDAR_ERROR_NONE)
+       {
+           calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+       }
+
+       list = NULL;
+       ret = _cal_db_attendee_convert_gtoh(event->attendee_list,event->index, &list);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+    }
+
+    if (event->exception_list)
+    {
+        DBG("insert exception");
+        list = NULL;
+        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, event->index, &list);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            calendar_db_insert_records(list, NULL, NULL);
+            calendar_list_destroy(list, false);
+        }
+    }
+
+    if (event->extended_list)
+    {
+        DBG("insert extended");
+        list = NULL;
+        ret = _cal_db_extended_convert_gtoh(event->extended_list, event->index, CALENDAR_RECORD_TYPE_EVENT, &list);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            calendar_db_insert_records(list, NULL, NULL);
+            calendar_list_destroy(list, false);
+        }
+    }
+
+       _cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_delete_record(int id)
+{
+       int ret;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       int calendar_book_id;
+       int account_id;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       calendar_record_h record_event;
+       calendar_record_h record_calendar;
+
+       retvm_if(id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid argument: id < 0");
+
+       ret = calendar_db_get_record(_calendar_event._uri, id, &record_event);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               DBG("calendar_db_get_record() failed");
+               return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
+       }
+       ret = calendar_record_get_int(record_event,
+                       _calendar_event.calendar_book_id, &calendar_book_id);
+       DBG("calendar_book_id(%d)", calendar_book_id);
+
+       ret = calendar_db_get_record(_calendar_book._uri,
+                       calendar_book_id, &record_calendar);
+       ret = calendar_record_get_int(record_calendar,
+                       _calendar_book.account_id, &account_id);
+       DBG("account_id(%d)", account_id);
+
+       if (account_id == LOCAL_ACCOUNT_ID) {
+               DBG("insert deleted table");
+               snprintf(query, sizeof(query),
+                               "INSERT INTO %s ( "
+                               "schedule_id, schedule_type, "
+                               "calendar_id, deleted_ver "
+                               ") VALUES ( "
+                               "%d, %d, "
+                               "%d, %d ) ",
+                               CAL_TABLE_DELETED,
+                               id, CAL_RECORD_TYPE_EVENT,
+                               calendar_book_id, _cal_db_util_get_next_ver());
+               DBG("query[%s]", query);
+
+               dbret = _cal_db_util_query_exec(query);
+               if(CAL_DB_OK != dbret)
+               {
+                       ERR("_cal_db_util_query_exec() Failed");
+                       calendar_record_destroy(record_event, true);
+                       calendar_record_destroy(record_calendar, true);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+
+               DBG("delete event");
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d ",
+                               CAL_TABLE_SCHEDULE, id);
+
+               dbret = _cal_db_util_query_exec(query);
+               if(CAL_DB_OK != dbret)
+               {
+                       DBG("query[%s]", query);
+                       ERR("_cal_db_util_query_exec() Failed");
+                       calendar_record_destroy(record_event, true);
+                       calendar_record_destroy(record_calendar, true);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+
+               DBG("attendee, alarm and rrule is deleted by trigger");
+
+       } else {
+               DBG("set is_delete");
+               snprintf(query, sizeof(query),
+                               "UPDATE %s "
+                               "SET is_deleted = 1, "
+                               "changed_ver = %d, "
+                               "last_mod = strftime('%%s','now') "
+                               "WHERE id = %d ",
+                               CAL_TABLE_SCHEDULE,
+                               _cal_db_util_get_next_ver(),
+                               id);
+
+               dbret = _cal_db_util_query_exec(query);
+               if (dbret != CAL_DB_OK)
+               {
+                       DBG("query[%s]", query);
+                       ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+                       calendar_record_destroy(record_event, true);
+                       calendar_record_destroy(record_calendar, true);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+
+               DBG("attendee, alarm and rrule will be deleted by trigger after sync clean");
+       }
+
+       ret = _cal_db_instance_discard_record(record_event);
+       retvm_if(ret != CALENDAR_ERROR_NONE, CALENDAR_ERROR_DB_FAILED,
+                       "_cal_db_instance_discard_record() Failed(%d)", ret);
+
+       ret = calendar_record_destroy(record_event, true);
+       ret = calendar_record_destroy(record_calendar, true);
+
+       _cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_get_all_records(int offset, int limit, calendar_list_h* out_list)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query), "SELECT * FROM %s %s %s", CAL_VIEW_TABLE_EVENT,limitquery,offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+               *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_event._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_event_get_stmt(stmt, true, record);
+
+        // child
+        int has_attendee = 0, has_alarm = 0;
+        int record_id = 0;
+        cal_event_s* pevent = (cal_event_s*) record;
+        calendar_record_get_int(record, _calendar_event.id, &record_id);
+        if(calendar_record_get_int(record, _calendar_event.has_attendee,&has_attendee) == CALENDAR_ERROR_NONE)
+        {
+            if( has_attendee == 1)
+            {
+                _cal_db_attendee_get_records(record_id, &pevent->attendee_list);
+            }
+        }
+        if(calendar_record_get_int(record, _calendar_event.has_alarm,&has_alarm) == CALENDAR_ERROR_NONE)
+        {
+            if( has_alarm == 1)
+            {
+                _cal_db_alarm_get_records(record_id, &pevent->alarm_list);
+            }
+        }
+
+        __cal_db_event_exception_get_records(record_id, &pevent->exception_list);
+        _cal_db_extended_get_records(record_id, CALENDAR_RECORD_TYPE_EVENT, &pevent->extended_list);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    sqlite3_finalize(stmt);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
+{
+    cal_query_s *que = NULL;
+       calendar_list_h list = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+    char *table_name;
+
+       if (NULL == query || NULL == out_list)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", table_name);
+    }
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(&list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_event._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(list, true);
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_event_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_event_get_stmt(stmt,true,record);
+        }
+
+        // child
+        if (_cal_db_query_find_projection_property(query,CAL_PROPERTY_EVENT_CALENDAR_ALARM) == true)
+        {
+            cal_event_s* pevent = (cal_event_s*) record;
+            _cal_db_alarm_get_records(pevent->index, &pevent->alarm_list);
+        }
+        if (_cal_db_query_find_projection_property(query,CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE) == true)
+        {
+            cal_event_s* pevent = (cal_event_s*) record;
+            _cal_db_attendee_get_records(pevent->index, &pevent->attendee_list);
+        }
+        if (_cal_db_query_find_projection_property(query,CAL_PROPERTY_EVENT_EXCEPTION) == true)
+        {
+            cal_event_s* pevent = (cal_event_s*) record;
+            __cal_db_event_exception_get_records(pevent->index, &pevent->exception_list);
+        }
+        if (_cal_db_query_find_projection_property(query,CAL_PROPERTY_EVENT_EXTENDED) == true)
+        {
+            cal_event_s* pevent = (cal_event_s*) record;
+            _cal_db_extended_get_records(pevent->index, CALENDAR_RECORD_TYPE_EVENT, &pevent->extended_list);
+        }
+
+        ret = calendar_list_add(list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(list, true);
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+
+    sqlite3_finalize(stmt);
+
+       *out_list = list;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_insert_records(const calendar_list_h list, int** ids)
+{
+    calendar_record_h record;
+    int ret = 0;
+    int count = 0;
+    int i=0;
+    int *id = NULL;
+
+    ret = calendar_list_get_count(list, &count);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list get error");
+        return ret;
+    }
+
+    id = calloc(1, sizeof(int)*count);
+
+    retvm_if(NULL == id, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc fail");
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        CAL_FREE(id);
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_event_insert_record(record, &id[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                CAL_FREE(id);
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+        i++;
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    if(ids)
+    {
+        *ids = id;
+    }
+    else
+    {
+        CAL_FREE(id);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_update_records(const calendar_list_h list)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_event_update_record(record) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_delete_records(int ids[], int count)
+{
+    int i=0;
+    for(i=0;i<count;i++)
+    {
+        if (__cal_db_event_delete_record(ids[i]) != CALENDAR_ERROR_NONE)
+        {
+            ERR("delete failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_VIEW_TABLE_EVENT);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_replace_record(calendar_record_h record, int id)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char dtstart_datetime[32] = {0};
+       char dtend_datetime[32] = {0};
+       sqlite3_stmt *stmt = NULL;
+       cal_event_s* event =  (cal_event_s*)(record);
+       cal_rrule_s *rrule = NULL;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+       int has_alarm = 0;
+       int timezone_id = 0;
+
+       retv_if(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (event->common.properties_flags != NULL)
+    {
+        return __cal_db_event_update_dirty(record);
+    }
+    has_alarm = _cal_db_alarm_has_alarm(event->alarm_list);
+       _cal_time_get_timezone_from_table(event->start_tzid, NULL, &timezone_id);
+       snprintf(query, sizeof(query), "UPDATE %s SET "
+                       "changed_ver = %d,"
+                       "type = %d,"
+                       "summary = ?,"
+                       "description = ?,"
+                       "location = ?,"
+                       "categories = ?,"
+                       "exdate = ?,"
+                       "task_status = %d,"
+                       "priority = %d,"
+                       "timezone = %d, "
+                       "contact_id = %d, "
+                       "busy_status = %d, "
+                       "sensitivity = %d, "
+                       "uid = ?, "
+                       "organizer_name = ?, "
+                       "organizer_email = ?, "
+                       "meeting_status = %d, "
+                       "calendar_id = %d, "
+                       "original_event_id = %d,"
+                       "latitude = %lf,"
+                       "longitude = %lf,"
+                       "email_id = %d,"
+               "availability = %d,"
+                       "completed_time = %lld,"
+                       "progress = %d, "
+                       "dtstart_type = %d, "
+                       "dtstart_utime = %lld, "
+                       "dtstart_datetime = ?, "
+                       "dtstart_tzid = ?, "
+                       "dtend_type = %d, "
+                       "dtend_utime = %lld, "
+                       "dtend_datetime = ?, "
+                       "dtend_tzid = ?, "
+                       "last_mod = strftime('%%s', 'now'), "
+                       "rrule_id = %d, "
+               "recurrence_id = ?, "
+               "rdate = ?, "
+               "has_attendee = %d, "
+               "has_alarm = %d, "
+               "system_type = %d, "
+               "updated = %ld, "
+               "sync_data1 = ?, "
+               "sync_data2 = ?, "
+               "sync_data3 = ?, "
+               "sync_data4 = ? "
+                       "WHERE id = %d ",
+               CAL_TABLE_SCHEDULE,
+               _cal_db_util_get_next_ver(),
+               CAL_SCH_TYPE_EVENT,/*event->cal_type,*/
+               event->event_status,
+               event->priority,
+               event->timezone ? event->timezone : timezone_id,
+               event->contact_id,
+               event->busy_status,
+               event->sensitivity,
+               event->meeting_status,
+               event->calendar_id,
+               event->original_event_id,
+               event->latitude,
+               event->longitude,
+               event->email_id,
+               0,//event->availability,
+               (long long int)0,//event->completed_time,
+               0,//event->progress,
+               event->start.type,
+               event->start.type == CALENDAR_TIME_UTIME ? event->start.time.utime : 0,
+               event->end.type,
+               event->end.type == CALENDAR_TIME_UTIME ? event->end.time.utime : 0,
+               event->freq > 0 ? 1 : 0,
+               event->attendee_list ? 1 : 0,
+               has_alarm,
+               event->system_type,
+               event->updated,
+               id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+       int index = 1;
+
+       if (event->summary)
+               _cal_db_util_stmt_bind_text(stmt, index, event->summary);
+       index++;
+
+       if (event->description)
+               _cal_db_util_stmt_bind_text(stmt, index, event->description);
+       index++;
+
+       if (event->location)
+               _cal_db_util_stmt_bind_text(stmt, index, event->location);
+       index++;
+
+       if (event->categories)
+               _cal_db_util_stmt_bind_text(stmt, index, event->categories);
+       index++;
+
+       if (event->exdate)
+               _cal_db_util_stmt_bind_text(stmt, index, event->exdate);
+       index++;
+
+       if (event->uid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->uid);
+       index++;
+
+       if (event->organizer_name)
+               _cal_db_util_stmt_bind_text(stmt, index, event->organizer_name);
+       index++;
+
+       if (event->organizer_email)
+               _cal_db_util_stmt_bind_text(stmt, index, event->organizer_email);
+       index++;
+
+       if (CALENDAR_TIME_LOCALTIME == event->start.type)
+       {
+               snprintf(dtstart_datetime, sizeof(dtstart_datetime), "%04d%02d%02d",
+                               event->start.time.date.year,
+                               event->start.time.date.month,
+                               event->start.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, index, dtstart_datetime);
+       }
+       index++;
+
+       if (event->start_tzid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->start_tzid);
+       index++;
+
+       if (CALENDAR_TIME_LOCALTIME == event->end.type)
+       {
+               snprintf(dtend_datetime, sizeof(dtend_datetime), "%04d%02d%02d",
+                               event->end.time.date.year,
+                               event->end.time.date.month,
+                               event->end.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, index, dtend_datetime);
+       }
+       index++;
+
+       if (event->end_tzid)
+               _cal_db_util_stmt_bind_text(stmt, index, event->end_tzid);
+       index++;
+
+    if (event->recurrence_id)
+        _cal_db_util_stmt_bind_text(stmt, index, event->recurrence_id);
+    index++;
+    if (event->rdate)
+        _cal_db_util_stmt_bind_text(stmt, index, event->rdate);
+    index++;
+    if (event->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data1);
+    index++;
+    if (event->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data2);
+    index++;
+    if (event->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data3);
+    index++;
+    if (event->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, index, event->sync_data4);
+    index++;
+
+    dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_DONE != dbret) {
+               sqlite3_finalize(stmt);
+               ERR("sqlite3_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+       sqlite3_finalize(stmt);
+
+       _cal_db_rrule_get_rrule_from_event(record, &rrule);
+       _cal_db_rrule_update_record(id, rrule);
+       CAL_FREE(rrule);
+
+       ret = _cal_db_instance_discard_record(record);
+       retvm_if(ret != CALENDAR_ERROR_NONE, CALENDAR_ERROR_DB_FAILED,
+                       "_cal_db_instance_discard_record() Failed(%d)", ret);
+
+       _cal_db_instance_publish_record(record);
+
+       _cal_db_alarm_delete_with_id(id);
+       _cal_db_attendee_delete_with_id(id);
+    __cal_db_event_exception_delete_with_id(id);
+    _cal_db_extended_delete_with_id(id, CALENDAR_RECORD_TYPE_EVENT);
+
+       calendar_list_h list;
+
+       list = NULL;
+       ret = _cal_db_alarm_convert_gtoh(event->alarm_list, id, &list);
+       if (ret == CALENDAR_ERROR_NONE)
+       {
+        calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+       }
+
+       list = NULL;
+       ret = _cal_db_attendee_convert_gtoh(event->attendee_list, id, &list);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+    }
+
+    if (event->exception_list)
+    {
+        DBG("insert exception");
+        list = NULL;
+        ret = __cal_db_event_exception_convert_gtoh(event->exception_list, id, &list);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            calendar_db_insert_records(list, NULL, NULL);
+            calendar_list_destroy(list, false);
+        }
+    }
+
+    if (event->extended_list)
+    {
+        DBG("insert extended");
+        list = NULL;
+        ret = _cal_db_extended_convert_gtoh(event->extended_list, id, CALENDAR_RECORD_TYPE_EVENT, &list);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            calendar_db_insert_records(list, NULL, NULL);
+            calendar_list_destroy(list, false);
+        }
+    }
+
+       _cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_replace_records(const calendar_list_h list, int ids[], int count)
+{
+    calendar_record_h record;
+       int i = 0;
+    int ret = 0;
+
+       if (NULL == list)
+       {
+               ERR("Invalid argument: list is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+
+       for (i = 0; i < count; i++)
+       {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_event_replace_record(record, ids[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+               if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
+               {
+                       break;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_event_get_stmt(sqlite3_stmt *stmt,bool is_view_table,calendar_record_h record)
+{
+    cal_event_s *event = NULL;
+    const unsigned char *temp;
+    int count = 0;
+    char *dtstart_datetime;
+    char *dtend_datetime;
+    char buf[8] = {0};
+
+    event = (cal_event_s*)(record);
+
+    event->index = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//event->account_id = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//event->cal_type = 1;/*sqlite3_column_int(stmt, count++);*/
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->summary = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    event->description = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->location = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->categories = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->exdate = SAFE_STRDUP(temp);
+
+    event->event_status = sqlite3_column_int(stmt, count++);
+    event->priority = sqlite3_column_int(stmt, count++);
+    event->timezone = sqlite3_column_int(stmt, count++);
+    event->contact_id = sqlite3_column_int(stmt, count++);
+    event->busy_status = sqlite3_column_int(stmt, count++);
+    event->sensitivity = sqlite3_column_int(stmt, count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->uid = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->organizer_name = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->organizer_email = SAFE_STRDUP(temp);
+
+    event->meeting_status = sqlite3_column_int(stmt, count++);
+
+    event->calendar_id = sqlite3_column_int(stmt, count++);
+
+    event->original_event_id = sqlite3_column_int(stmt, count++);
+
+    event->latitude = sqlite3_column_double(stmt,count++);
+    event->longitude = sqlite3_column_double(stmt,count++);
+    event->email_id = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//event->availability = sqlite3_column_int(stmt, count++);
+
+    event->created_time = sqlite3_column_int64(stmt, count++);
+
+    sqlite3_column_int64(stmt, count++);//event->completed_time = sqlite3_column_int64(stmt, count++);
+
+    sqlite3_column_int(stmt, count++);//event->progress = sqlite3_column_int(stmt,count++);
+
+    sqlite3_column_int(stmt,count++);
+    sqlite3_column_int(stmt,count++);
+    event->is_deleted = sqlite3_column_int(stmt,count++);
+
+    event->start.type = sqlite3_column_int(stmt,count++);
+
+    if (event->start.type == CALENDAR_TIME_UTIME)
+    {
+        event->start.time.utime = sqlite3_column_int64(stmt,count++);
+        sqlite3_column_text(stmt, count++);  //dtstart_datetime
+    }
+    else
+    {
+        sqlite3_column_int64(stmt,count++); //event->start.time.utime = sqlite3_column_int64(stmt,count++);
+        temp = sqlite3_column_text(stmt, count++);
+        if (temp) {
+            dtstart_datetime = SAFE_STRDUP(temp);
+            snprintf(buf, strlen("YYYY") + 1, "%s", &dtstart_datetime[0]);
+            event->start.time.date.year =  atoi(buf);
+            snprintf(buf, strlen("MM") + 1, "%s", &dtstart_datetime[4]);
+            event->start.time.date.month = atoi(buf);
+            snprintf(buf, strlen("DD") + 1, "%s", &dtstart_datetime[6]);
+            event->start.time.date.mday = atoi(buf);
+            if (dtstart_datetime) free(dtstart_datetime);
+        }
+    }
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->start_tzid = SAFE_STRDUP(temp);
+    event->end.type = sqlite3_column_int(stmt, count++);
+    if (event->end.type == CALENDAR_TIME_UTIME)
+    {
+        event->end.time.utime = sqlite3_column_int64(stmt,count++);
+        sqlite3_column_text(stmt, count++);
+    }
+    else
+    {
+        sqlite3_column_int64(stmt, count++);//event->end.time.utime = sqlite3_column_int64(stmt, count++);
+        temp = sqlite3_column_text(stmt, count++);
+        if (temp) {
+            dtend_datetime = SAFE_STRDUP(temp);
+            snprintf(buf, strlen("YYYY") + 1, "%s", &dtend_datetime[0]);
+            event->end.time.date.year =  atoi(buf);
+            snprintf(buf, strlen("MM") + 1, "%s", &dtend_datetime[4]);
+            event->end.time.date.month = atoi(buf);
+            snprintf(buf, strlen("DD") + 1, "%s", &dtend_datetime[6]);
+            event->end.time.date.mday = atoi(buf);
+            if (dtend_datetime) free(dtend_datetime);
+        }
+    }
+    temp = sqlite3_column_text(stmt, count++);
+    event->end_tzid = SAFE_STRDUP(temp);
+
+    event->last_mod = sqlite3_column_int64(stmt,count++);
+    sqlite3_column_int(stmt,count++);//event->rrule_id = sqlite3_column_int(stmt,count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    event->recurrence_id = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    event->rdate = SAFE_STRDUP(temp);
+    event->has_attendee = sqlite3_column_int(stmt,count++);
+    event->has_alarm = sqlite3_column_int(stmt,count++);
+    event->system_type = sqlite3_column_int(stmt,count++);
+    event->updated = sqlite3_column_int(stmt,count++);
+    temp = sqlite3_column_text(stmt, count++);
+    event->sync_data1 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    event->sync_data2 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    event->sync_data3 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    event->sync_data4 = SAFE_STRDUP(temp);
+
+    if (is_view_table == true)
+    {
+        event->freq = sqlite3_column_int(stmt, count++);
+
+        if (event->freq <= 0) {
+            //event->rrule_id = 0;
+            //sqlite3_finalize(stmt);
+            //return CALENDAR_ERROR_NONE;
+            return ;
+        }
+
+        //event->rrule_id = 1;
+        event->range_type = sqlite3_column_int(stmt, count++);
+        event->until_type = sqlite3_column_int(stmt, count++);
+        event->until_utime = sqlite3_column_int64(stmt, count++);
+
+        temp = sqlite3_column_text(stmt, count++);
+               if (CALENDAR_TIME_LOCALTIME == event->until_type)
+               {
+                       sscanf((const char *)temp, "%04d%02d%02d",
+                                       &event->until_year, &event->until_month, &event->until_mday);
+               }
+
+        event->count = sqlite3_column_int(stmt, count++);
+        event->interval = sqlite3_column_int(stmt, count++);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->bysecond = SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->byminute = SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->byhour = SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->byday= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->bymonthday= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->byyearday= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->byweekno= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->bymonth= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        event->bysetpos = SAFE_STRDUP(temp);
+
+        event->wkst = sqlite3_column_int(stmt, count++);
+
+        sqlite3_column_int(stmt, count++); //calendar deleted
+    }
+
+}
+
+static void __cal_db_event_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record)
+{
+    cal_event_s *event = NULL;
+    const unsigned char *temp;
+    char *dtstart_datetime;
+    char *dtend_datetime;
+    char buf[8] = {0};
+
+    event = (cal_event_s*)(record);
+
+    switch(property)
+    {
+    case CAL_PROPERTY_EVENT_ID:
+        event->index = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_ID:
+        event->calendar_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_SUMMARY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->summary = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_DESCRIPTION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->description = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_LOCATION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->location = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_CATEGORIES:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->categories = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_EXDATE:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->exdate = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_EVENT_STATUS:
+        event->event_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_PRIORITY:
+        event->priority = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_TIMEZONE:
+        event->timezone = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_CONTACT_ID:
+        event->contact_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_BUSY_STATUS:
+        event->busy_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_SENSITIVITY:
+        event->sensitivity = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_UID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->uid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_NAME:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->organizer_name = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_ORGANIZER_EMAIL:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->organizer_email = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_MEETING_STATUS:
+        event->meeting_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID:
+        event->original_event_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_LATITUDE:
+        event->latitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_LONGITUDE:
+        event->longitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_EMAIL_ID:
+        event->email_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_CREATED_TIME:
+        event->created_time = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME:
+        event->last_mod = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_IS_DELETED:
+        event->is_deleted = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_FREQ:
+        event->freq = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_RANGE_TYPE:
+        event->range_type = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_UNTIL:
+        //!!
+        break;
+    case CAL_PROPERTY_EVENT_COUNT:
+        event->count = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_INTERVAL:
+        event->interval = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_BYSECOND:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->bysecond = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYMINUTE:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->byminute = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYHOUR:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->byhour = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYDAY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->byday = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTHDAY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->bymonthday = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYYEARDAY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->byyearday = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYWEEKNO:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->byweekno = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYMONTH:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->bymonth = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_BYSETPOS:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->bysetpos = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_WKST:
+        event->wkst = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_RECURRENCE_ID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->recurrence_id = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_RDATE:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->rdate = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_HAS_ATTENDEE:
+        event->has_attendee = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_HAS_ALARM:
+        event->has_alarm = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA1:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->sync_data1 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA2:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->sync_data2 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA3:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->sync_data3 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_SYNC_DATA4:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->sync_data4 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_START:
+        //!!
+        event->start.type = sqlite3_column_int(stmt,*stmt_count);
+        if (event->start.type == CALENDAR_TIME_UTIME)
+        {
+            *stmt_count = *stmt_count+1;
+            event->start.time.utime = sqlite3_column_int64(stmt,*stmt_count);
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_text(stmt, *stmt_count);  //dtstart_datetime
+        }
+        else
+        {
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_int64(stmt,*stmt_count); //event->start.time.utime = sqlite3_column_int64(stmt,count++);
+            *stmt_count = *stmt_count+1;
+            temp = sqlite3_column_text(stmt, *stmt_count);
+            if (temp) {
+                dtstart_datetime = SAFE_STRDUP(temp);
+                snprintf(buf, strlen("YYYY") + 1, "%s", &dtstart_datetime[0]);
+                event->start.time.date.year =  atoi(buf);
+                snprintf(buf, strlen("MM") + 1, "%s", &dtstart_datetime[4]);
+                event->start.time.date.month = atoi(buf);
+                snprintf(buf, strlen("DD") + 1, "%s", &dtstart_datetime[6]);
+                event->start.time.date.mday = atoi(buf);
+                if (dtstart_datetime) free(dtstart_datetime);
+            }
+        }
+        break;
+    case CAL_PROPERTY_EVENT_START_TZID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->start_tzid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_END:
+        //!!
+        event->end.type = sqlite3_column_int(stmt, *stmt_count);
+        if (event->end.type == CALENDAR_TIME_UTIME)
+        {
+            *stmt_count = *stmt_count+1;
+            event->end.time.utime = sqlite3_column_int64(stmt,*stmt_count);
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_text(stmt, *stmt_count);
+        }
+        else
+        {
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_int64(stmt, *stmt_count);//event->end.time.utime = sqlite3_column_int64(stmt, count++);
+            *stmt_count = *stmt_count+1;
+            temp = sqlite3_column_text(stmt, *stmt_count);
+            if (temp) {
+                dtend_datetime = SAFE_STRDUP(temp);
+                snprintf(buf, strlen("YYYY") + 1, "%s", &dtend_datetime[0]);
+                event->end.time.date.year =  atoi(buf);
+                snprintf(buf, strlen("MM") + 1, "%s", &dtend_datetime[4]);
+                event->end.time.date.month = atoi(buf);
+                snprintf(buf, strlen("DD") + 1, "%s", &dtend_datetime[6]);
+                event->end.time.date.mday = atoi(buf);
+                if (dtend_datetime) free(dtend_datetime);
+            }
+        }
+        break;
+    case CAL_PROPERTY_EVENT_END_TZID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        event->end_tzid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE:
+        event->system_type = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    default:
+        sqlite3_column_int(stmt, *stmt_count);
+        break;
+    }
+
+    *stmt_count = *stmt_count+1;
+}
+
+static void __cal_db_event_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_event_get_property_stmt(stmt,projection[i],&stmt_count,record);
+    }
+}
+
+static int __cal_db_event_update_dirty(calendar_record_h record)
+{
+    int event_id = 0;
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_record_h original_record = NULL;
+
+    ret = calendar_record_get_int(record,_calendar_event.id, &event_id);
+    retv_if(CALENDAR_ERROR_NONE != ret, ret);
+
+    CAL_DBG("id=%d",event_id);
+
+    ret = __cal_db_event_get_record(event_id, &original_record);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        cal_record_s *_record = NULL;
+        const cal_property_info_s* property_info = NULL;
+        int property_info_count = 0;
+        int i=0;
+
+        _record = (cal_record_s *)record;
+
+        property_info = _cal_view_get_property_info(_record->view_uri, &property_info_count);
+
+        for(i=0;i<property_info_count;i++)
+        {
+            if ( true == _cal_record_check_property_flag(record, property_info[i].property_id , CAL_PROPERTY_FLAG_DIRTY))
+            {
+                //CAL_DBG("%d",property_info[i].property_id);
+                if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_INT) == true)
+                {
+                    int tmp=0;
+                    ret = calendar_record_get_int(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_int(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_STR) == true)
+                {
+                    char *tmp=NULL;
+                    ret = calendar_record_get_str_p(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_str(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+                {
+                    double tmp=0;
+                    ret = calendar_record_get_double(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_double(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_LLI) == true)
+                {
+                    long long int tmp=0;
+                    ret = calendar_record_get_lli(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_lli(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+                {
+                    calendar_time_s tmp = {0,};
+                    ret = calendar_record_get_caltime(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_caltime(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+            }
+        }
+
+        // child replace
+        cal_event_s *tmp = (cal_event_s *)original_record;
+        cal_event_s *tmp_src = (cal_event_s *)record;
+        if ( tmp->alarm_list )
+        {
+            GList *alarm_list = g_list_first(tmp->alarm_list);
+            calendar_record_h alarm_child_record = NULL;
+            while (alarm_list)
+            {
+                alarm_child_record = (calendar_record_h)alarm_list->data;
+                if (alarm_child_record == NULL)
+                {
+                    alarm_list = g_list_next(alarm_list);
+                    continue;
+                }
+
+                calendar_record_destroy(alarm_child_record, true);
+
+                alarm_list = g_list_next(alarm_list);
+            }
+            g_list_free(tmp->alarm_list);
+        }
+        tmp->alarm_list = tmp_src->alarm_list;
+
+        if( tmp->attendee_list )
+        {
+            GList * attendee_list = g_list_first(tmp->attendee_list);
+            calendar_record_h attendee = NULL;
+
+            while (attendee_list)
+            {
+                attendee = (calendar_record_h)attendee_list->data;
+                if (attendee == NULL)
+                {
+                    attendee_list = g_list_next(attendee_list);
+                    continue;
+                }
+
+                calendar_record_destroy(attendee, true);
+
+                attendee_list = g_list_next(attendee_list);
+            }
+            g_list_free(tmp->attendee_list);
+        }
+        tmp->attendee_list = tmp_src->attendee_list;
+        if( tmp->exception_list )
+        {
+            GList * exception_list = g_list_first(tmp->exception_list);
+            calendar_record_h exception = NULL;
+
+            while (exception_list)
+            {
+                exception = (calendar_record_h)exception_list->data;
+                if (exception == NULL)
+                {
+                    exception_list = g_list_next(exception_list);
+                    continue;
+                }
+
+                calendar_record_destroy(exception, true);
+
+                exception_list = g_list_next(exception_list);
+            }
+            g_list_free(tmp->exception_list);
+        }
+        tmp->exception_list = tmp_src->exception_list;
+        if( tmp->extended_list )
+        {
+            GList * extended_list = g_list_first(tmp->extended_list);
+            calendar_record_h extended = NULL;
+
+            while (extended_list)
+            {
+                extended = (calendar_record_h)extended_list->data;
+                if (extended == NULL)
+                {
+                    extended_list = g_list_next(extended_list);
+                    continue;
+                }
+
+                calendar_record_destroy(extended, true);
+
+                extended_list = g_list_next(extended_list);
+            }
+            g_list_free(tmp->extended_list);
+        }
+        tmp->extended_list = tmp_src->extended_list;
+    }
+    else
+    {
+        CAL_DBG("get_record fail");
+        return ret;
+    }
+
+    CAL_RECORD_RESET_COMMON((cal_record_s*)original_record);
+    ret = __cal_db_event_update_record(original_record);
+
+    calendar_record_destroy(original_record,false);
+
+    return ret;
+}
+
+#if 0 // // under construction
+static int __cal_db_event_update_dirty(calendar_record_h record)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_event_s* event =  (cal_event_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int ret = CALENDAR_ERROR_NONE;
+    char* set = NULL;
+    GSList *bind_text = NULL;
+    unsigned int properties[36];
+    int properties_count = 36;
+    bool bchangerrule = __cal_db_event_check_changed_rrule(record);
+    bool bchangetime = __cal_db_event_check_changed_time(record);
+
+    if (bchangerrule == true && bchangetime == false)
+    {
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+    /*
+    else if (bchangetime == true)
+    {
+        // rrule table check !
+    }
+    */
+
+    properties[0] = CAL_PROPERTY_EVENT_CALENDAR_ID;
+    properties[1] = CAL_PROPERTY_EVENT_SUMMARY;
+    properties[2] = CAL_PROPERTY_EVENT_DESCRIPTION;
+    properties[3] = CAL_PROPERTY_EVENT_LOCATION;
+    properties[4] = CAL_PROPERTY_EVENT_CATEGORIES;
+    properties[5] = CAL_PROPERTY_EVENT_EXDATE;
+    properties[6] = CAL_PROPERTY_EVENT_EVENT_STATUS;
+    properties[7] = CAL_PROPERTY_EVENT_PRIORITY;
+    properties[8] = CAL_PROPERTY_EVENT_TIMEZONE;
+    properties[9] = CAL_PROPERTY_EVENT_CONTACT_ID;
+    properties[10] = CAL_PROPERTY_EVENT_BUSY_STATUS;
+    properties[11] = CAL_PROPERTY_EVENT_SENSITIVITY;
+    properties[12] = CAL_PROPERTY_EVENT_UID;
+    properties[13] = CAL_PROPERTY_EVENT_ORGANIZER_NAME;
+    properties[14] = CAL_PROPERTY_EVENT_ORGANIZER_EMAIL;
+    properties[15] = CAL_PROPERTY_EVENT_MEETING_STATUS;
+    properties[16] = CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID;
+    properties[17] = CAL_PROPERTY_EVENT_LATITUDE;
+    properties[18] = CAL_PROPERTY_EVENT_LONGITUDE;
+    properties[19] = CAL_PROPERTY_EVENT_EMAIL_ID;
+    properties[20] = CAL_PROPERTY_EVENT_CREATED_TIME;
+    properties[21] = CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME;
+    properties[22] = CAL_PROPERTY_EVENT_IS_DELETED;
+    properties[23] = CAL_PROPERTY_EVENT_RECURRENCE_ID;
+    properties[24] = CAL_PROPERTY_EVENT_RDATE;
+    properties[25] = CAL_PROPERTY_EVENT_HAS_ATTENDEE;
+    properties[26] = CAL_PROPERTY_EVENT_HAS_ALARM;
+    properties[27] = CAL_PROPERTY_EVENT_SYNC_DATA1;
+    properties[28] = CAL_PROPERTY_EVENT_SYNC_DATA2;
+    properties[29] = CAL_PROPERTY_EVENT_SYNC_DATA3;
+    properties[30] = CAL_PROPERTY_EVENT_SYNC_DATA4;
+    properties[31] = CAL_PROPERTY_EVENT_START;
+    properties[32] = CAL_PROPERTY_EVENT_END;
+    properties[33] = CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE;
+    properties[34] = CAL_PROPERTY_EVENT_START_TZID;
+    properties[35] = CAL_PROPERTY_EVENT_END_TZID;
+
+    ret = _cal_db_query_create_projection_update_set_with_property(record,properties,properties_count,
+            &set,&bind_text);
+    retv_if(CALENDAR_ERROR_NONE != ret, ret);
+
+    if (set && strlen(str) > 0)
+    {
+        snprintf(query, sizeof(query), "UPDATE %s SET "
+                "changed_ver = %d, "
+                "%s"
+                "WHERE id = %d",
+                CAL_TABLE_SCHEDULE,
+                _cal_db_util_get_next_ver(),
+                set,
+                event->index);
+    }
+    else
+    {
+        snprintf(query, sizeof(query), "UPDATE %s SET "
+                "changed_ver = %d"
+                "WHERE id = %d",
+                CAL_TABLE_SCHEDULE,
+                _cal_db_util_get_next_ver(),
+                event->index);
+    }
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    // bind
+    if (bind_text)
+    {
+        int len;
+        GSList *cursor = NULL;
+        int i = 0;
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret) {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+
+        CAL_FREE(set);
+        if(bind_text)
+        {
+            for (cursor=bind_text; cursor;cursor=cursor->next)
+            {
+                CAL_FREE(cursor->data);
+            }
+            g_slist_free(bind_text);
+        }
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    sqlite3_finalize(stmt);
+
+    // rrule update
+    if (bchangerrule == true)
+    {
+        cal_rrule_s *rrule = NULL;
+
+        _cal_db_rrule_get_rrule_from_event(record, &rrule);
+        _cal_db_rrule_update_record(event->index, rrule);
+        CAL_FREE(rrule);
+
+        ret = _cal_db_instance_discard_record(record);
+        retvm_if(ret != CALENDAR_ERROR_NONE, CALENDAR_ERROR_DB_FAILED,
+                "_cal_db_instance_discard_record() Failed(%d)", ret);
+
+        _cal_db_instance_publish_record(record);
+    }
+
+    // child update 의 경우는 get_with_query 구현 이후 고려
+
+    _cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
+
+    CAL_FREE(set);
+    if(bind_text)
+    {
+        for (cursor=bind_text; cursor;cursor=cursor->next)
+        {
+            CAL_FREE(cursor->data);
+        }
+        g_slist_free(bind_text);
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+bool __cal_db_event_check_changed_rrule(calendar_record_h record)
+{
+    unsigned int properties[15];
+    int properties_count = 15;
+    int i=0;
+
+    properties[0] = CAL_PROPERTY_EVENT_FREQ;
+    properties[1] = CAL_PROPERTY_EVENT_RANGE_TYPE;
+    properties[2] = CAL_PROPERTY_EVENT_UNTIL;
+    properties[3] = CAL_PROPERTY_EVENT_COUNT;
+    properties[4] = CAL_PROPERTY_EVENT_INTERVAL;
+    properties[5] = CAL_PROPERTY_EVENT_BYSECOND;
+    properties[6] = CAL_PROPERTY_EVENT_BYMINUTE;
+    properties[7] = CAL_PROPERTY_EVENT_BYHOUR;
+    properties[8] = CAL_PROPERTY_EVENT_BYDAY;
+    properties[9] = CAL_PROPERTY_EVENT_BYMONTHDAY;
+    properties[10] = CAL_PROPERTY_EVENT_BYYEARDAY;
+    properties[11] = CAL_PROPERTY_EVENT_BYWEEKNO;
+    properties[12] = CAL_PROPERTY_EVENT_BYMONTH;
+    properties[13] = CAL_PROPERTY_EVENT_BYSETPOS;
+    properties[14] = CAL_PROPERTY_EVENT_WKST;
+
+    for(i=0;i<properties_count;i++)
+    {
+        if (false == _cal_record_check_property_flag(record, properties[i], CAL_PROPERTY_FLAG_PROJECTION))
+            return false;
+    }
+    return true;
+}
+
+bool __cal_db_event_check_changed_time(calendar_record_h record)
+{
+    unsigned int properties[2];
+    int properties_count = 2;
+    int i=0;
+
+    properties[0] = CAL_PROPERTY_EVENT_START;
+    properties[1] = CAL_PROPERTY_EVENT_END;
+
+    for(i=0;i<properties_count;i++)
+    {
+        if (false == _cal_record_check_property_flag(record, properties[i], CAL_PROPERTY_FLAG_PROJECTION))
+            return false;
+    }
+    return true;
+}
+#endif
+
+static int __cal_db_event_exception_get_records(int original_id, GList **out_list)
+{
+    int ret;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    GList *list = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter: GList is NULL");
+
+    snprintf(query, sizeof(query),
+            "SELECT * FROM %s "
+            "WHERE original_event_id = %d ",
+            CAL_TABLE_SCHEDULE,
+            original_id);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    calendar_record_h record = NULL;
+
+    while (_cal_db_util_stmt_step(stmt) == CAL_DB_ROW)
+    {
+        ret = calendar_record_create(_calendar_event._uri, &record);
+        if (CALENDAR_ERROR_NONE != ret)
+        {
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+
+        __cal_db_event_get_stmt(stmt, false, record);
+
+        list = g_list_append(list, record);
+    }
+    sqlite3_finalize(stmt);
+
+    *out_list = list;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_exception_convert_gtoh(GList *glist, int original_id, calendar_list_h *hlist)
+{
+    int ret;
+    GList *g = NULL;
+    calendar_list_h h = NULL;
+    calendar_record_h exception = NULL;
+
+    if (glist == NULL)
+    {
+        DBG("No attendee");
+        return CALENDAR_ERROR_NO_DATA;
+    }
+    ret = calendar_list_create(&h);
+
+    g = g_list_first(glist);
+    while (g)
+    {
+        exception = (calendar_record_h)g->data;
+        if (exception)
+        {
+            ret = _cal_record_set_int(exception,_calendar_event.original_event_id, original_id);
+            ret = calendar_list_add(h, exception);
+
+        }
+        g = g_list_next(g);
+    }
+
+    *hlist = h;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_event_exception_delete_with_id(int original_id)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    snprintf(query, sizeof(query), "DELETE FROM %s WHERE original_event_id=%d ",
+            CAL_TABLE_SCHEDULE, original_id);
+
+    dbret = _cal_db_util_query_exec(query);
+    if (dbret != CAL_DB_OK) {
+        ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/native/cal_db_plugin_extended.c b/native/cal_db_plugin_extended.c
new file mode 100644 (file)
index 0000000..fb8f08f
--- /dev/null
@@ -0,0 +1,880 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+
+static int __cal_db_extended_insert_record( calendar_record_h record, int* id );
+static int __cal_db_extended_get_record( int id, calendar_record_h* out_record );
+static int __cal_db_extended_update_record( calendar_record_h record );
+static int __cal_db_extended_delete_record( int id );
+static int __cal_db_extended_get_all_records( int offset, int limit, calendar_list_h* out_list );
+static int __cal_db_extended_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list );
+static int __cal_db_extended_insert_records(const calendar_list_h list, int** ids);
+static int __cal_db_extended_update_records(const calendar_list_h list);
+static int __cal_db_extended_delete_records(int ids[], int count);
+static int __cal_db_extended_get_count(int *out_count);
+static int __cal_db_extended_get_count_with_query(calendar_query_h query, int *out_count);
+static int __cal_db_extended_replace_record(calendar_record_h record, int id);
+static int __cal_db_extended_replace_records(const calendar_list_h list, int ids[], int count);
+
+/*
+ * static function
+ */
+static void __cal_db_extended_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static void __cal_db_extended_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int stmt_count, calendar_record_h record);
+static void __cal_db_extended_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+static void __cal_db_extended_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static int __cal_db_extended_update_projection(calendar_record_h record);
+
+cal_db_plugin_cb_s _cal_db_extended_plugin_cb = {
+    .is_query_only=false,
+    .insert_record=__cal_db_extended_insert_record,
+    .get_record=__cal_db_extended_get_record,
+    .update_record=__cal_db_extended_update_record,
+    .delete_record=__cal_db_extended_delete_record,
+    .get_all_records=__cal_db_extended_get_all_records,
+    .get_records_with_query=__cal_db_extended_get_records_with_query,
+    .insert_records=__cal_db_extended_insert_records,
+    .update_records=__cal_db_extended_update_records,
+    .delete_records=__cal_db_extended_delete_records,
+    .get_count=__cal_db_extended_get_count,
+    .get_count_with_query=__cal_db_extended_get_count_with_query,
+    .replace_record = __cal_db_extended_replace_record,
+    .replace_records = __cal_db_extended_replace_records
+};
+
+static int __cal_db_extended_insert_record( calendar_record_h record, int* id )
+{
+    int index;
+    sqlite3_stmt *stmt;
+    char query[CAL_DB_SQL_MAX_LEN];
+    cal_extended_s* extended =  (cal_extended_s*)(record);
+    cal_db_util_error_e dbret;
+
+    retv_if(NULL == extended, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    sprintf(query,"INSERT INTO %s(record_id, "
+            "record_type ,key ,value) "
+            "VALUES(%d,%d,?,?)",
+            CAL_TABLE_EXTENDED,
+            extended->record_id,
+            extended->record_type);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    if (extended->key)
+        _cal_db_util_stmt_bind_text(stmt, 1, extended->key);
+
+    if (extended->value)
+        _cal_db_util_stmt_bind_text(stmt, 2, extended->value);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+    index = _cal_db_util_last_insert_id();
+    sqlite3_finalize(stmt);
+
+    //_cal_record_set_int(record, _calendar_extended.id,index);
+    if (id)
+    {
+        *id = index;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_get_record( int id, calendar_record_h* out_record )
+{
+    cal_extended_s *extended=NULL;
+    char query[CAL_DB_SQL_MAX_LEN];
+    sqlite3_stmt *stmt = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int ret = 0;
+
+    ret = calendar_record_create( _calendar_extended_property._uri ,out_record);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("record create fail");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+
+    extended = (cal_extended_s*)(*out_record);
+
+    snprintf(query, sizeof(query), "SELECT * FROM %s WHERE id=%d",
+            CAL_TABLE_EXTENDED, id);
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_record_destroy(*out_record, true);
+        *out_record = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_ROW != dbret)
+       {
+        ERR("_cal_db_util_stmt_step() failed(%d)", dbret);
+        sqlite3_finalize(stmt);
+        calendar_record_destroy(*out_record, true);
+        *out_record = NULL;
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    __cal_db_extended_get_stmt(stmt,*out_record);
+
+    sqlite3_finalize(stmt);
+    stmt = NULL;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_update_record( calendar_record_h record )
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_extended_s* extended_info =  (cal_extended_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    retv_if(NULL == extended_info, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (extended_info->common.properties_flags != NULL)
+    {
+        return __cal_db_extended_update_projection(record);
+    }
+
+    sprintf(query, "UPDATE %s SET "
+            "record_id=%d,"
+            "record_type=%d,"
+            "key=?,"
+            "value=? "
+            "WHERE id = %d",
+            CAL_TABLE_EXTENDED,
+            extended_info->record_id,
+            extended_info->record_type,
+            extended_info->id);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "cal_q_cal_db_util_query_prepareuery_prepare() Failed");
+
+    if (extended_info->key)
+        _cal_db_util_stmt_bind_text(stmt, 1, extended_info->key);
+
+    if (extended_info->value)
+        _cal_db_util_stmt_bind_text(stmt, 2, extended_info->value);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    sqlite3_finalize(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        ERR("cal_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_delete_record( int id )
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d",
+            CAL_TABLE_EXTENDED, id);
+    dbret = _cal_db_util_query_exec(query);
+    if(CAL_DB_OK != dbret)
+       {
+        ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_replace_record(calendar_record_h record, int id)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_extended_s* extended_info =  (cal_extended_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    retv_if(NULL == extended_info, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (extended_info->common.properties_flags != NULL)
+    {
+        return __cal_db_extended_update_projection(record);
+    }
+
+    sprintf(query, "UPDATE %s SET "
+            "record_id=%d,"
+            "record_type=%d,"
+            "key=?,"
+            "value=? "
+            "WHERE id = %d",
+            CAL_TABLE_EXTENDED,
+            extended_info->record_id,
+            extended_info->record_type,
+            id);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "cal_q_cal_db_util_query_prepareuery_prepare() Failed");
+
+    if (extended_info->key)
+        _cal_db_util_stmt_bind_text(stmt, 1, extended_info->key);
+
+    if (extended_info->value)
+        _cal_db_util_stmt_bind_text(stmt, 2, extended_info->value);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    sqlite3_finalize(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_get_all_records( int offset, int limit, calendar_list_h* out_list )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query), "SELECT * FROM %s %s %s", CAL_TABLE_EXTENDED,limitquery,offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+        *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_extended_property._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_extended_get_stmt(stmt,record);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    sqlite3_finalize(stmt);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list )
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+
+    que = (cal_query_s *)query;
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, CAL_TABLE_EXTENDED);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", CAL_TABLE_EXTENDED);
+    }
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_extended_property._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+            _cal_record_set_projection(record,
+                    que->projection, que->projection_count, que->property_count);
+
+            __cal_db_extended_get_projection_stmt(stmt,
+                    que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_extended_get_stmt(stmt,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+            *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+static int __cal_db_extended_insert_records(const calendar_list_h list, int** ids)
+{
+    calendar_record_h record;
+    int ret = 0;
+    int count = 0;
+    int i=0;
+    int *id = NULL;
+
+    ret = calendar_list_get_count(list, &count);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list get error");
+        return ret;
+    }
+
+    id = calloc(1, sizeof(int)*count);
+
+    retvm_if(NULL == id, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc fail");
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        CAL_FREE(id);
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_extended_insert_record(record, &id[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                CAL_FREE(id);
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+        i++;
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    if(ids)
+    {
+        *ids = id;
+    }
+    else
+    {
+        CAL_FREE(id);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_update_records(const calendar_list_h list)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_extended_update_record(record) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_delete_records(int ids[], int count)
+{
+    int i=0;
+    for(i=0;i<count;i++)
+    {
+        if (__cal_db_extended_delete_record(ids[i]) != CALENDAR_ERROR_NONE)
+        {
+            ERR("delete failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_replace_records(const calendar_list_h list, int ids[], int count)
+{
+    calendar_record_h record;
+    int i;
+    int ret = 0;
+
+    if (NULL == list)
+    {
+        ERR("Invalid argument: list is NULL");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+
+    for (i = 0; i < count; i++)
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_extended_replace_record(record, ids[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+        if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
+        {
+            break;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_EXTENDED);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_extended_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EXTENDED))
+    {
+        table_name = SAFE_STRDUP(CAL_TABLE_EXTENDED);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_extended_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
+{
+    cal_extended_s* extended =  (cal_extended_s*)(record);
+    int count = 0;
+    const unsigned char *temp;
+
+    extended->id = sqlite3_column_int(stmt, count++);
+    extended->record_id = sqlite3_column_int(stmt, count++);
+    extended->record_type = sqlite3_column_int(stmt, count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    extended->key = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    extended->value = SAFE_STRDUP(temp);
+}
+
+static void __cal_db_extended_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int stmt_count, calendar_record_h record)
+{
+    cal_extended_s* extended =  (cal_extended_s*)(record);
+    const unsigned char *temp;
+
+    switch(property)
+    {
+    case CAL_PROPERTY_EXTENDED_ID:
+        extended->id = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_EXTENDED_RECORD_ID:
+        extended->record_id = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_EXTENDED_RECORD_TYPE:
+        extended->record_type = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_EXTENDED_KEY:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        extended->key = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_EXTENDED_VALUE:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        extended->value = SAFE_STRDUP(temp);
+        break;
+    default:
+        sqlite3_column_int(stmt, stmt_count);
+        break;
+    }
+
+    return;
+}
+
+static void __cal_db_extended_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_extended_get_property_stmt(stmt,projection[i],i,record);
+    }
+}
+
+static int __cal_db_extended_update_projection(calendar_record_h record)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_extended_s* extended =  (cal_extended_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int ret = CALENDAR_ERROR_NONE;
+    char* set = NULL;
+    GSList *bind_text = NULL;
+    int len;
+    GSList *cursor = NULL;
+
+    ret = _cal_db_query_create_projection_update_set(record,&set,&bind_text);
+    retv_if(CALENDAR_ERROR_NONE != ret, ret);
+
+    snprintf(query, sizeof(query), "UPDATE %s SET %s "
+            "WHERE id = %d",
+            CAL_TABLE_EXTENDED,set,
+            extended->id);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    // bind
+    if (bind_text)
+    {
+        int i = 0;
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+
+        CAL_FREE(set);
+        if(bind_text)
+        {
+            for (cursor=bind_text; cursor;cursor=cursor->next)
+            {
+                CAL_FREE(cursor->data);
+            }
+            g_slist_free(bind_text);
+        }
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    sqlite3_finalize(stmt);
+
+    CAL_FREE(set);
+    if(bind_text)
+    {
+        for (cursor=bind_text; cursor;cursor=cursor->next)
+        {
+            CAL_FREE(cursor->data);
+        }
+        g_slist_free(bind_text);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/native/cal_db_plugin_instance_allday.c b/native/cal_db_plugin_instance_allday.c
new file mode 100644 (file)
index 0000000..a8d1367
--- /dev/null
@@ -0,0 +1,692 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+
+static int __cal_db_instance_allday_insert_record(calendar_record_h record, int* id);
+//static int __cal_db_instance_allday_get_record(int id, calendar_record_h* out_record);
+//static int __cal_db_instance_allday_update_record(calendar_record_h record);
+static int __cal_db_instance_allday_delete_record(int id);
+static int __cal_db_instance_allday_get_all_records(int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_instance_allday_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
+//static int __cal_db_instance_allday_insert_records(const calendar_list_h list);
+//static int __cal_db_instance_allday_update_records(const calendar_list_h list);
+//static int __cal_db_instance_allday_delete_records(int ids[], int count);
+static int __cal_db_instance_allday_get_count(int *out_count);
+static int __cal_db_instance_allday_get_count_with_query(calendar_query_h query, int *out_count);
+
+/*
+ * static function
+ */
+static void __cal_db_instance_allday_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static void __cal_db_instance_allday_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record);
+static void __cal_db_instance_allday_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+
+cal_db_plugin_cb_s _cal_db_instance_allday_plugin_cb = {
+       .is_query_only = false,
+       .insert_record=__cal_db_instance_allday_insert_record,
+       .get_record=NULL,
+       .update_record=NULL,
+       .delete_record=__cal_db_instance_allday_delete_record,
+       .get_all_records=__cal_db_instance_allday_get_all_records,
+       .get_records_with_query=__cal_db_instance_allday_get_records_with_query,
+       .insert_records=NULL,
+       .update_records=NULL,
+       .delete_records=NULL,
+    .get_count=__cal_db_instance_allday_get_count,
+    .get_count_with_query=__cal_db_instance_allday_get_count_with_query,
+    .replace_record=NULL,
+    .replace_records=NULL
+};
+
+static int __cal_db_instance_allday_insert_record(calendar_record_h record, int* id)
+{
+       int index = -1;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+       cal_instance_allday_s *allday = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       allday = (cal_instance_allday_s *)(record);
+       retvm_if(NULL == allday, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: cal_instance_allday_s is NULL");
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s ("
+                       "event_id, "
+                       "dtstart_datetime, dtend_datetime"
+                       ") VALUES ( "
+                       "%d, "
+                       "%04d%02d%02d, %04d%02d%02d) ",
+                       CAL_TABLE_ALLDAY_INSTANCE,
+                       allday->event_id,
+                       allday->dtstart_year, allday->dtstart_month, allday->dtstart_mday,
+                       allday->dtend_year, allday->dtend_month, allday->dtend_mday);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               sqlite3_finalize(stmt);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       index = _cal_db_util_last_insert_id();
+       sqlite3_finalize(stmt);
+
+       //calendar_record_set_int(record, _calendar_instance_allday.id, index);
+    if (id)
+    {
+        *id = index;
+    }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_allday_delete_record(int id)
+{
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       retvm_if(id < 0, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: id(%d) < 0", id);
+
+       snprintf(query, sizeof(query),
+                       "DELETE FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_ALLDAY_INSTANCE,
+                       id);
+
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_allday_get_all_records(int offset, int limit, calendar_list_h* out_list)
+{
+        int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query),
+                       "SELECT * FROM %s %s %s",
+                       CAL_TABLE_ALLDAY_INSTANCE, limitquery, offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+               *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_instance_allday._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_instance_allday_get_stmt(stmt,record);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+    sqlite3_finalize(stmt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_allday_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+    char *table_name;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_ALLDAY_INSTANCE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_ALLDAY_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", table_name);
+    }
+
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(que->view_uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_instance_allday_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_instance_allday_get_stmt(stmt,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                for (cursor=bind_text;cursor;cursor=cursor->next)
+                {
+                    CAL_FREE(cursor->data);
+                }
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_allday_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_ALLDAY_INSTANCE);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_allday_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_ALLDAY_INSTANCE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_ALLDAY_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    if (out_count) *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_instance_allday_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
+{
+    cal_instance_allday_s* instance =  (cal_instance_allday_s*)(record);
+    const unsigned char *temp;
+    char *dtstart_datetime;
+    char *dtend_datetime;
+    char buf[8] = {0};
+    int count = 0;
+
+    instance->event_id = sqlite3_column_int(stmt, count++);
+    instance->dtstart_type = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int64(stmt, count++);//instance->dtstart_utime = sqlite3_column_int64(stmt, count++);
+    temp = sqlite3_column_text(stmt, count++);
+    if (temp) {
+        dtstart_datetime = SAFE_STRDUP(temp);
+        snprintf(buf, strlen("YYYY") + 1, "%s", &dtstart_datetime[0]);
+        instance->dtstart_year =  atoi(buf);
+        snprintf(buf, strlen("MM") + 1, "%s", &dtstart_datetime[4]);
+        instance->dtstart_month = atoi(buf);
+        snprintf(buf, strlen("DD") + 1, "%s", &dtstart_datetime[6]);
+        instance->dtstart_mday = atoi(buf);
+        if (dtstart_datetime)
+            free(dtstart_datetime);
+    }
+
+    instance->dtend_type = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int64(stmt, count++);//instance->dtend_utime = sqlite3_column_int64(stmt, count++);
+    temp = sqlite3_column_text(stmt, count++);
+    if (temp) {
+        dtend_datetime = SAFE_STRDUP(temp);
+        snprintf(buf, strlen("YYYY") + 1, "%s", &dtend_datetime[0]);
+        instance->dtend_year =  atoi(buf);
+        snprintf(buf, strlen("MM") + 1, "%s", &dtend_datetime[4]);
+        instance->dtend_month = atoi(buf);
+        snprintf(buf, strlen("DD") + 1, "%s", &dtend_datetime[6]);
+        instance->dtend_mday = atoi(buf);
+        if (dtend_datetime)
+            free(dtend_datetime);
+    }
+
+    temp = sqlite3_column_text(stmt, count++);
+    instance->summary = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    instance->description = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    instance->location = SAFE_STRDUP(temp);
+
+    instance->busy_status = sqlite3_column_int(stmt, count++);
+
+    instance->event_status = sqlite3_column_int(stmt, count++);
+
+    instance->priority = sqlite3_column_int(stmt, count++);
+
+    instance->sensitivity = sqlite3_column_int(stmt, count++);
+
+    instance->has_rrule = sqlite3_column_int(stmt, count++);
+    if (instance->has_rrule > 0)
+    {
+        instance->has_rrule = 1;
+    }
+
+    instance->latitude = sqlite3_column_double(stmt,count++);
+    instance->longitude = sqlite3_column_double(stmt,count++);
+    instance->has_alarm = sqlite3_column_int(stmt,count++);
+    instance->original_event_id = sqlite3_column_int(stmt, count++);
+    instance->calendar_id = sqlite3_column_int(stmt, count++);
+    instance->last_mod = sqlite3_column_int64(stmt, count++);
+
+    return;
+}
+
+static void __cal_db_instance_allday_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record)
+{
+    cal_instance_allday_s* instance =  (cal_instance_allday_s*)(record);
+    const unsigned char *temp;
+    char *dtstart_datetime;
+    char *dtend_datetime;
+    char buf[8] = {0};
+
+    switch(property)
+    {
+    case CAL_PROPERTY_INSTANCE_ALLDAY_START:
+        sqlite3_column_int(stmt,*stmt_count);
+        *stmt_count = *stmt_count+1;
+        sqlite3_column_int64(stmt,*stmt_count);
+        *stmt_count = *stmt_count+1;
+        instance->dtstart_type = CALENDAR_TIME_LOCALTIME;//sqlite3_column_int(stmt, *stmt_count);
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        if (temp) {
+            dtstart_datetime = SAFE_STRDUP(temp);
+            snprintf(buf, strlen("YYYY") + 1, "%s", &dtstart_datetime[0]);
+            instance->dtstart_year =  atoi(buf);
+            snprintf(buf, strlen("MM") + 1, "%s", &dtstart_datetime[4]);
+            instance->dtstart_month = atoi(buf);
+            snprintf(buf, strlen("DD") + 1, "%s", &dtstart_datetime[6]);
+            instance->dtstart_mday = atoi(buf);
+            if (dtstart_datetime)
+                free(dtstart_datetime);
+        }
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_END:
+        sqlite3_column_int(stmt,*stmt_count);
+        *stmt_count = *stmt_count+1;
+        sqlite3_column_int64(stmt,*stmt_count);
+        *stmt_count = *stmt_count+1;
+        instance->dtend_type = CALENDAR_TIME_LOCALTIME; //sqlite3_column_int(stmt, *stmt_count);
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        if (temp) {
+            dtend_datetime = SAFE_STRDUP(temp);
+            snprintf(buf, strlen("YYYY") + 1, "%s", &dtend_datetime[0]);
+            instance->dtend_year =  atoi(buf);
+            snprintf(buf, strlen("MM") + 1, "%s", &dtend_datetime[4]);
+            instance->dtend_month = atoi(buf);
+            snprintf(buf, strlen("DD") + 1, "%s", &dtend_datetime[6]);
+            instance->dtend_mday = atoi(buf);
+            if (dtend_datetime)
+                free(dtend_datetime);
+        }
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_SUMMARY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        instance->summary = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LOCATION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        instance->location = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_CALENDAR_ID:
+        instance->calendar_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_DESCRIPTION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        instance->description = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_BUSY_STATUS:
+        instance->busy_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_STATUS:
+        instance->event_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_PRIORITY:
+        instance->priority = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_SENSITIVITY:
+        instance->sensitivity = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_HAS_RRULE:
+        instance->has_rrule = sqlite3_column_int(stmt, *stmt_count);
+        if (instance->has_rrule > 0)
+        {
+            instance->has_rrule = 1;
+        }
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LATITUDE:
+        instance->latitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LONGITUDE:
+        instance->longitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_EVENT_ID:
+        instance->event_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_HAS_ALARM:
+        instance->has_alarm = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_ORIGINAL_EVENT_ID:
+        instance->original_event_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_ALLDAY_LAST_MODIFIED_TIME:
+        instance->last_mod = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    default:
+        sqlite3_column_int(stmt, *stmt_count);
+        break;
+    }
+
+    *stmt_count = *stmt_count+1;
+
+    return;
+}
+
+static void __cal_db_instance_allday_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_instance_allday_get_property_stmt(stmt,projection[i],&stmt_count,record);
+    }
+}
diff --git a/native/cal_db_plugin_instance_normal.c b/native/cal_db_plugin_instance_normal.c
new file mode 100644 (file)
index 0000000..7abad1f
--- /dev/null
@@ -0,0 +1,632 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+
+static int __cal_db_instance_normal_insert_record(calendar_record_h record, int* id);
+//static int __cal_db_instance_normal_get_record(int id, calendar_record_h* out_record);
+//static int __cal_db_instance_normal_update_record(calendar_record_h record);
+static int __cal_db_instance_normal_delete_record(int id);
+static int __cal_db_instance_normal_get_all_records(int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_instance_normal_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
+//static int __cal_db_instance_normal_insert_records(const calendar_list_h list);
+//static int __cal_db_instance_normal_update_records(const calendar_list_h list);
+//static int __cal_db_instance_normal_delete_records(int ids[], int count);
+static int __cal_db_instance_normal_get_count(int *out_count);
+static int __cal_db_instance_normal_get_count_with_query(calendar_query_h query, int *out_count);
+/*
+ * static function
+ */
+static void __cal_db_instance_normal_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static void __cal_db_instance_normal_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record);
+static void __cal_db_instance_normal_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+
+cal_db_plugin_cb_s _cal_db_instance_normal_plugin_cb = {
+       .is_query_only = false,
+       .insert_record=__cal_db_instance_normal_insert_record,
+       .get_record=NULL,
+       .update_record=NULL,
+       .delete_record=__cal_db_instance_normal_delete_record,
+       .get_all_records=__cal_db_instance_normal_get_all_records,
+       .get_records_with_query=__cal_db_instance_normal_get_records_with_query,
+       .insert_records=NULL,
+       .update_records=NULL,
+       .delete_records=NULL,
+    .get_count=__cal_db_instance_normal_get_count,
+    .get_count_with_query=__cal_db_instance_normal_get_count_with_query,
+    .replace_record=NULL,
+    .replace_records=NULL
+};
+
+static int __cal_db_instance_normal_insert_record(calendar_record_h record, int* id)
+{
+       int index = -1;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+       cal_instance_normal_s *normal = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       normal = (cal_instance_normal_s *)(record);
+       retvm_if(NULL == normal, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: cal_instance_normal_s is NULL");
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s ("
+                       "event_id, "
+                       "dtstart_utime, dtend_utime"
+                       ") VALUES ( "
+                       "%d, "
+                       "%lld, %lld) ",
+                       CAL_TABLE_NORMAL_INSTANCE,
+                       normal->event_id,
+                       normal->dtstart_utime, normal->dtend_utime);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               sqlite3_finalize(stmt);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       index = _cal_db_util_last_insert_id();
+       sqlite3_finalize(stmt);
+
+       //calendar_record_set_int(record, _calendar_instance_normal.id, index);
+       if (id)
+       {
+           *id = index;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_normal_delete_record(int id)
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+
+       retvm_if(id < 0, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: id(%d) < 0", id);
+
+       snprintf(query, sizeof(query),
+                       "DELETE FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_NORMAL_INSTANCE,
+                       id);
+
+       dbret = _cal_db_util_query_exec(query);
+       if (dbret != CAL_DB_OK)
+       {
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_normal_get_all_records(int offset, int limit, calendar_list_h* out_list)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query),
+                       "SELECT * FROM %s %s %s",
+                       CAL_TABLE_NORMAL_INSTANCE, limitquery, offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+               *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW ==  _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_instance_normal._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_instance_normal_get_stmt(stmt,record);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+    sqlite3_finalize(stmt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_normal_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+    char *table_name;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_NORMAL_INSTANCE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", table_name);
+    }
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(que->view_uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_instance_normal_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_instance_normal_get_stmt(stmt,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_normal_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_TABLE_NORMAL_INSTANCE);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_instance_normal_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_NORMAL_INSTANCE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    if (out_count) *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_instance_normal_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
+{
+    cal_instance_normal_s* instance =  (cal_instance_normal_s*)(record);
+    const unsigned char *temp;
+    int count = 0;
+
+    instance->event_id = sqlite3_column_int(stmt, count++);
+    instance->dtstart_type = sqlite3_column_int(stmt, count++);
+    instance->dtstart_utime = sqlite3_column_int64(stmt, count++);
+    sqlite3_column_text(stmt, count++);  //datetime
+    instance->dtend_type = sqlite3_column_int(stmt, count++);
+    instance->dtend_utime = sqlite3_column_int64(stmt, count++);
+    sqlite3_column_text(stmt, count++);  //datetime
+
+    temp = sqlite3_column_text(stmt, count++);
+    instance->summary = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    instance->description = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    instance->location = SAFE_STRDUP(temp);
+
+    instance->busy_status = sqlite3_column_int(stmt, count++);
+
+    instance->event_status = sqlite3_column_int(stmt, count++);
+
+    instance->priority = sqlite3_column_int(stmt, count++);
+
+    instance->sensitivity = sqlite3_column_int(stmt, count++);
+
+    instance->has_rrule = sqlite3_column_int(stmt, count++);
+    if (instance->has_rrule > 0)
+    {
+        instance->has_rrule = 1;
+    }
+
+    instance->latitude = sqlite3_column_double(stmt,count++);
+    instance->longitude = sqlite3_column_double(stmt,count++);
+    instance->has_alarm = sqlite3_column_int(stmt,count++);
+    instance->original_event_id = sqlite3_column_int(stmt, count++);
+    instance->calendar_id = sqlite3_column_int(stmt, count++);
+    instance->last_mod = sqlite3_column_int64(stmt, count++);
+
+    return;
+}
+
+static void __cal_db_instance_normal_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record)
+{
+    cal_instance_normal_s* instance =  (cal_instance_normal_s*)(record);
+    const unsigned char *temp;
+
+    switch(property)
+    {
+    case CAL_PROPERTY_INSTANCE_NORMAL_START:
+        sqlite3_column_int(stmt,*stmt_count);
+        *stmt_count = *stmt_count+1;
+        instance->dtstart_type = CALENDAR_TIME_UTIME;//sqlite3_column_int(stmt, *stmt_count);
+        instance->dtstart_utime = sqlite3_column_int64(stmt, *stmt_count);
+        *stmt_count = *stmt_count+1;
+        sqlite3_column_text(stmt, *stmt_count);  // dtstart_datetime
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_END:
+        sqlite3_column_int(stmt,*stmt_count);
+        *stmt_count = *stmt_count+1;
+        instance->dtend_type = CALENDAR_TIME_UTIME;//sqlite3_column_int(stmt, *stmt_count);
+        instance->dtend_utime = sqlite3_column_int64(stmt, *stmt_count);
+        *stmt_count = *stmt_count+1;
+        sqlite3_column_text(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_SUMMARY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        instance->summary = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LOCATION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        instance->location = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_CALENDAR_ID:
+        instance->calendar_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_DESCRIPTION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        instance->description = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_BUSY_STATUS:
+        instance->busy_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_STATUS:
+        instance->event_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_PRIORITY:
+        instance->priority = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_SENSITIVITY:
+        instance->sensitivity = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_HAS_RRULE:
+        instance->has_rrule = sqlite3_column_int(stmt, *stmt_count);
+        if (instance->has_rrule > 0)
+        {
+            instance->has_rrule = 1;
+        }
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LATITUDE:
+        instance->latitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LONGITUDE:
+        instance->longitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_EVENT_ID:
+        instance->event_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_HAS_ALARM:
+        instance->has_alarm = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_ORIGINAL_EVENT_ID:
+        instance->original_event_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_INSTANCE_NORMAL_LAST_MODIFIED_TIME:
+        instance->last_mod = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    default:
+        sqlite3_column_int(stmt, *stmt_count);
+        break;
+    }
+
+    *stmt_count = *stmt_count+1;
+
+    return;
+}
+
+static void __cal_db_instance_normal_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_instance_normal_get_property_stmt(stmt,projection[i],&stmt_count,record);
+    }
+}
diff --git a/native/cal_db_plugin_search.c b/native/cal_db_plugin_search.c
new file mode 100644 (file)
index 0000000..8e6a533
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db.h"
+#include "cal_db_util.h"
+#include "cal_db_query.h"
+
+/*
+ * db plugin function
+ */
+static int __cal_db_search_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list );
+static int __cal_db_search_get_count_with_query(calendar_query_h query, int *out_count);
+
+/*
+ * static function
+ */
+static void __cal_db_search_get_stmt(sqlite3_stmt *stmt,calendar_query_h query,
+        calendar_record_h record);
+static void __cal_db_search_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record);
+static void __cal_db_search_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+static int __cal_db_search_make_projection(calendar_query_h query, char **projection);
+
+
+cal_db_plugin_cb_s _cal_db_search_plugin_cb = {
+    .is_query_only=true,
+    .insert_record=NULL,
+    .get_record=NULL,
+    .update_record=NULL,
+    .delete_record=NULL,
+    .get_all_records=NULL,
+    .get_records_with_query=__cal_db_search_get_records_with_query,
+    .insert_records=NULL,
+    .update_records=NULL,
+    .delete_records=NULL,
+    .get_count=NULL,
+    .get_count_with_query=__cal_db_search_get_count_with_query,
+    .replace_record=NULL,
+    .replace_records=NULL
+};
+
+static int __cal_db_search_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list )
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+    char *table_name;
+
+    que = (cal_query_s *)query;
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    if (que->projection_count > 0)
+    {
+        ret = _cal_db_query_create_projection(query, &projection);
+    }
+    else
+    {
+        __cal_db_search_make_projection(query, &projection);
+    }
+
+    // query - projection
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_TODO_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_TODO_CALENDAR);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_NORMAL_INSTANCE);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_ALLDAY_INSTANCE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (que->distinct == true)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT DISTINCT %s FROM %s", projection, table_name);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
+    }
+
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(que->view_uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+            __cal_db_search_get_projection_stmt(stmt,que->projection,que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_search_get_stmt(stmt, query,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_search_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR);
+        projection = SAFE_STRDUP("id");
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_TODO_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_TODO_CALENDAR);
+        projection = SAFE_STRDUP("id");
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE);
+        projection = SAFE_STRDUP("id");
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_NORMAL_INSTANCE);
+        projection = SAFE_STRDUP("event_id");
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_ALLDAY_INSTANCE);
+        projection = SAFE_STRDUP("event_id");
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            CAL_FREE(projection);
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    if (que->distinct == true)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT count(DISTINCT %s) FROM %s", projection, table_name);
+
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+    }
+
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               CAL_FREE(projection);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_search_get_stmt(sqlite3_stmt *stmt,calendar_query_h query,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+    cal_query_s *query_s = NULL;
+    cal_property_info_s *properties = NULL;
+
+    query_s = (cal_query_s *)query;
+
+    for (i=0;i<query_s->property_count;i++)
+    {
+        properties = &(query_s->properties[i]);
+
+        if ( CAL_PROPERTY_CHECK_FLAGS(properties->property_id, CAL_PROPERTY_FLAGS_FILTER) == true)
+        {
+            break;
+        }
+
+        __cal_db_search_get_property_stmt(stmt, properties->property_id, &stmt_count,record);
+    }
+    return ;
+}
+
+static void __cal_db_search_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record)
+{
+    cal_search_s *search = NULL;
+    const unsigned char *temp;
+    char *dtstart_datetime;
+    char buf[8] = {0};
+    int int_tmp = 0;
+    double d_tmp = 0;
+    long long int lli_tmp = 0;
+
+    search = (cal_search_s*)(record);
+
+    if (CAL_PROPERTY_CHECK_DATA_TYPE(property,CAL_PROPERTY_DATA_TYPE_INT) == true)
+    {
+        int_tmp = sqlite3_column_int(stmt, *stmt_count);
+        _cal_record_set_int(record,property,int_tmp);
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(property,CAL_PROPERTY_DATA_TYPE_STR) == true)
+    {
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        _cal_record_set_str(record,property,(const char*)temp);
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(property,CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+    {
+        d_tmp = sqlite3_column_double(stmt,*stmt_count);
+        _cal_record_set_double(record,property,d_tmp);
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(property,CAL_PROPERTY_DATA_TYPE_LLI) == true)
+    {
+        lli_tmp = sqlite3_column_int64(stmt, *stmt_count);
+        _cal_record_set_lli(record,property,lli_tmp);
+    }
+    else if (CAL_PROPERTY_CHECK_DATA_TYPE(property,CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+    {
+        calendar_time_s caltime_tmp;
+        caltime_tmp.type = sqlite3_column_int(stmt,*stmt_count);
+        if (caltime_tmp.type == CALENDAR_TIME_UTIME)
+        {
+            *stmt_count = *stmt_count+1;
+            caltime_tmp.time.utime = sqlite3_column_int64(stmt,*stmt_count);
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_text(stmt, *stmt_count);
+        }
+        else
+        {
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_int64(stmt,*stmt_count); //event->start.time.utime = sqlite3_column_int64(stmt,count++);
+            *stmt_count = *stmt_count+1;
+            temp = sqlite3_column_text(stmt, *stmt_count);
+            if (temp) {
+                dtstart_datetime = SAFE_STRDUP(temp);
+                snprintf(buf, strlen("YYYY") + 1, "%s", &dtstart_datetime[0]);
+                caltime_tmp.time.date.year =  atoi(buf);
+                snprintf(buf, strlen("MM") + 1, "%s", &dtstart_datetime[4]);
+                caltime_tmp.time.date.month = atoi(buf);
+                snprintf(buf, strlen("DD") + 1, "%s", &dtstart_datetime[6]);
+                caltime_tmp.time.date.mday = atoi(buf);
+                if (dtstart_datetime) free(dtstart_datetime);
+            }
+        }
+        _cal_record_set_caltime(record,property,caltime_tmp);
+    }
+    else
+    {
+        sqlite3_column_int(stmt, *stmt_count);
+    }
+
+    *stmt_count = *stmt_count+1;
+}
+static void __cal_db_search_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_search_get_property_stmt(stmt,projection[i],&stmt_count,record);
+    }
+}
+
+static int __cal_db_search_make_projection(calendar_query_h query, char **projection)
+{
+    int i = 0;
+    int len = 0;
+    const char *field_name;
+    char out_projection[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_query_s *query_s = NULL;
+    cal_property_info_s *properties = NULL;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    query_s = (cal_query_s *)query;
+
+    properties = &(query_s->properties[0]);
+    field_name = properties->fields;
+    if (field_name)
+        len += snprintf(out_projection+len, sizeof(out_projection)-len, "%s", field_name);
+
+    for (i=1;i<query_s->property_count;i++)
+    {
+        properties = &(query_s->properties[i]);
+        field_name = properties->fields;
+
+        if ( CAL_PROPERTY_CHECK_FLAGS(properties->property_id, CAL_PROPERTY_FLAGS_FILTER) == true)
+        {
+            break;
+        }
+
+        if (field_name)
+        {
+            len += snprintf(out_projection+len, sizeof(out_projection)-len, ", %s", field_name);
+        }
+    }
+
+    *projection = strdup(out_projection);
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/native/cal_db_plugin_timezone.c b/native/cal_db_plugin_timezone.c
new file mode 100644 (file)
index 0000000..d1eb7cb
--- /dev/null
@@ -0,0 +1,1075 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "calendar_db.h"  //calendar_db_get_record
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+
+static int __cal_db_timezone_insert_record( calendar_record_h record, int* id );
+static int __cal_db_timezone_get_record( int id, calendar_record_h* out_record );
+static int __cal_db_timezone_update_record( calendar_record_h record );
+static int __cal_db_timezone_delete_record( int id );
+static int __cal_db_timezone_get_all_records( int offset, int limit, calendar_list_h* out_list );
+static int __cal_db_timezone_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list );
+static int __cal_db_timezone_insert_records(const calendar_list_h list, int** ids);
+static int __cal_db_timezone_update_records(const calendar_list_h list);
+static int __cal_db_timezone_delete_records(int ids[], int count);
+static int __cal_db_timezone_get_count(int *out_count);
+static int __cal_db_timezone_get_count_with_query(calendar_query_h query, int *out_count);
+static int __cal_db_timezone_replace_record(calendar_record_h record, int id);
+static int __cal_db_timezone_replace_records(const calendar_list_h list, int ids[], int count);
+
+/*
+ * static function
+ */
+static void __cal_db_timezone_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static void __cal_db_timezone_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int stmt_count, calendar_record_h record);
+static void __cal_db_timezone_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+static void __cal_db_timezone_get_stmt(sqlite3_stmt *stmt,calendar_record_h record);
+static int __cal_db_timezone_update_projection(calendar_record_h record);
+
+cal_db_plugin_cb_s _cal_db_timezone_plugin_cb = {
+    .is_query_only=false,
+    .insert_record=__cal_db_timezone_insert_record,
+    .get_record=__cal_db_timezone_get_record,
+    .update_record=__cal_db_timezone_update_record,
+    .delete_record=__cal_db_timezone_delete_record,
+    .get_all_records=__cal_db_timezone_get_all_records,
+    .get_records_with_query=__cal_db_timezone_get_records_with_query,
+    .insert_records=__cal_db_timezone_insert_records,
+    .update_records=__cal_db_timezone_update_records,
+    .delete_records=__cal_db_timezone_delete_records,
+    .get_count=__cal_db_timezone_get_count,
+    .get_count_with_query=__cal_db_timezone_get_count_with_query,
+    .replace_record = __cal_db_timezone_replace_record,
+    .replace_records = __cal_db_timezone_replace_records
+};
+
+static int __cal_db_timezone_insert_record( calendar_record_h record, int* id )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    int index;
+    int calendar_book_id = 0;
+    char query[CAL_DB_SQL_MAX_LEN];
+    sqlite3_stmt *stmt;
+    cal_timezone_s* timezone =  (cal_timezone_s*)(record);
+    calendar_record_h record_calendar = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    retv_if(NULL == timezone, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    ret = calendar_record_get_int(record,
+            _calendar_timezone.calendar_book_id, &calendar_book_id);
+    DBG("calendar_book_id(%d)", calendar_book_id);
+
+    ret = calendar_db_get_record(_calendar_book._uri,
+            calendar_book_id, &record_calendar);
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "calendar_book_id is invalid");
+    calendar_record_destroy(record_calendar, true);
+
+       // start >>>>> check if we already have
+/*
+       if (timezone->standard_name == NULL || strlen(timezone->standard_name) == 0)
+       {
+               ERR("No timezone starndard name");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+*/
+       if (timezone->standard_name)
+       {
+               snprintf(query, sizeof(query), "SELECT count(*), id FROM %s "
+                               "WHERE standard_name = ? ",
+                               CAL_TABLE_TIMEZONE);
+
+               stmt = _cal_db_util_query_prepare(query);
+               if (NULL == stmt)
+               {
+                       ERR("_cal_db_util_query_prepare() failed");
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+               _cal_db_util_stmt_bind_text(stmt, 1, timezone->standard_name);
+
+               dbret = _cal_db_util_stmt_step(stmt);
+               if (CAL_DB_ROW != dbret)
+               {
+                       ERR("_cal_db_util_stmt_step() failed");
+                       sqlite3_finalize(stmt);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+
+               index = 0;
+               int count = sqlite3_column_int(stmt, index++);
+               int timezone_id = sqlite3_column_int(stmt, index++);
+               sqlite3_finalize(stmt);
+
+               if (count > 0)
+               {
+                       DBG("Already exist which tzid name[%s] id(%d)", timezone->standard_name, timezone_id);
+                       *id = timezone_id;
+                       return CALENDAR_ERROR_NONE;
+               }
+               // end <<<<< check if we already have
+
+               DBG("Not registered timezone in the table, so insert timezone.");
+       }
+
+       // if we don't have
+    snprintf(query, sizeof(query), "INSERT INTO %s(tz_offset_from_gmt ,standard_name, "
+            "std_start_month ,std_start_position_of_week ,std_start_day, "
+            "std_start_hour ,standard_bias ,day_light_name ,day_light_start_month, "
+            "day_light_start_position_of_week ,day_light_start_day, "
+            "day_light_start_hour ,day_light_bias, calendar_id) "
+            "VALUES(%d,?,%d,%d,%d,%d,%d,?,%d,%d,%d,%d,%d,%d)",
+            CAL_TABLE_TIMEZONE,
+            timezone->tz_offset_from_gmt,
+            timezone->std_start_month,
+            timezone->std_start_position_of_week,
+            timezone->std_start_day,
+            timezone->std_start_hour,
+            timezone->standard_bias,
+            timezone->day_light_start_month,
+            timezone->day_light_start_position_of_week,
+            timezone->day_light_start_day,
+            timezone->day_light_start_hour,
+            timezone->day_light_bias,
+            timezone->calendar_id);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    if (timezone->standard_name)
+        _cal_db_util_stmt_bind_text(stmt, 1, timezone->standard_name);
+
+    if (timezone->day_light_name)
+        _cal_db_util_stmt_bind_text(stmt, 2, timezone->day_light_name);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+    index = _cal_db_util_last_insert_id();
+    sqlite3_finalize(stmt);
+
+    //_cal_record_set_int(record, _calendar_timezone.id,index);
+    if (id)
+    {
+        *id = index;
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_get_record( int id, calendar_record_h* out_record )
+{
+    cal_timezone_s *timezone=NULL;
+    char query[CAL_DB_SQL_MAX_LEN];
+    sqlite3_stmt *stmt = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int ret = 0;
+
+    ret = calendar_record_create( _calendar_timezone._uri ,out_record);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("record create fail");
+        return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+
+    timezone = (cal_timezone_s*)(*out_record);
+
+    snprintf(query, sizeof(query), "SELECT * FROM %s WHERE id = %d AND "
+            "calendar_id IN (select id from %s where deleted = 0)",
+            CAL_TABLE_TIMEZONE, id,
+            CAL_TABLE_CALENDAR);
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_ROW != dbret)
+       {
+        ERR("_cal_db_util_stmt_step() failed(%d)", dbret);
+        sqlite3_finalize(stmt);
+        calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    __cal_db_timezone_get_stmt(stmt,*out_record);
+
+    sqlite3_finalize(stmt);
+    stmt = NULL;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_update_record( calendar_record_h record )
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_timezone_s* timezone_info =  (cal_timezone_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    retv_if(NULL == timezone_info, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (timezone_info->common.properties_flags != NULL)
+    {
+        return __cal_db_timezone_update_projection(record);
+    }
+
+    sprintf(query, "UPDATE %s SET "
+            "tz_offset_from_gmt=%d,"
+            "standard_name=?,"
+            "std_start_month=%d,"
+            "std_start_position_of_week=%d,"
+            "std_start_day=%d,"
+            "std_start_hour=%d,"
+            "standard_bias=%d,"
+            "day_light_name=?,"
+            "day_light_start_month=%d,"
+            "day_light_start_position_of_week=%d,"
+            "day_light_start_day=%d,"
+            "day_light_start_hour=%d,"
+            "day_light_bias=%d, "
+            "calendar_id=%d "
+            "WHERE id = %d",
+            CAL_TABLE_TIMEZONE,
+            timezone_info->tz_offset_from_gmt,
+            timezone_info->std_start_month,
+            timezone_info->std_start_position_of_week,
+            timezone_info->std_start_day,
+            timezone_info->std_start_hour,
+            timezone_info->standard_bias,
+            timezone_info->day_light_start_month,
+            timezone_info->day_light_start_position_of_week,
+            timezone_info->day_light_start_day,
+            timezone_info->day_light_start_hour,
+            timezone_info->day_light_bias,
+            timezone_info->calendar_id,
+            timezone_info->index);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "cal_q_cal_db_util_query_prepareuery_prepare() Failed");
+
+    if (timezone_info->standard_name)
+        _cal_db_util_stmt_bind_text(stmt, 1, timezone_info->standard_name);
+
+    if (timezone_info->day_light_name)
+        _cal_db_util_stmt_bind_text(stmt, 2, timezone_info->day_light_name);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_delete_record( int id )
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d",
+            CAL_TABLE_TIMEZONE, id);
+    dbret = _cal_db_util_query_exec(query);
+       if(CAL_DB_OK != dbret)
+       {
+        ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_replace_record(calendar_record_h record, int id)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_timezone_s* timezone_info =  (cal_timezone_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    retv_if(NULL == timezone_info, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    if (timezone_info->common.properties_flags != NULL)
+    {
+        return __cal_db_timezone_update_projection(record);
+    }
+
+    sprintf(query, "UPDATE %s SET "
+            "tz_offset_from_gmt=%d,"
+            "standard_name=?,"
+            "std_start_month=%d,"
+            "std_start_position_of_week=%d,"
+            "std_start_day=%d,"
+            "std_start_hour=%d,"
+            "standard_bias=%d,"
+            "day_light_name=?,"
+            "day_light_start_month=%d,"
+            "day_light_start_position_of_week=%d,"
+            "day_light_start_day=%d,"
+            "day_light_start_hour=%d,"
+            "day_light_bias=%d, "
+            "calendar_id=%d "
+            "WHERE id = %d",
+            CAL_TABLE_TIMEZONE,
+            timezone_info->tz_offset_from_gmt,
+            timezone_info->std_start_month,
+            timezone_info->std_start_position_of_week,
+            timezone_info->std_start_day,
+            timezone_info->std_start_hour,
+            timezone_info->standard_bias,
+            timezone_info->day_light_start_month,
+            timezone_info->day_light_start_position_of_week,
+            timezone_info->day_light_start_day,
+            timezone_info->day_light_start_hour,
+            timezone_info->day_light_bias,
+            timezone_info->calendar_id,
+                       id);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "cal_q_cal_db_util_query_prepareuery_prepare() Failed");
+
+    if (timezone_info->standard_name)
+        _cal_db_util_stmt_bind_text(stmt, 1, timezone_info->standard_name);
+
+    if (timezone_info->day_light_name)
+        _cal_db_util_stmt_bind_text(stmt, 2, timezone_info->day_light_name);
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    sqlite3_finalize(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_get_all_records( int offset, int limit, calendar_list_h* out_list )
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query), "SELECT * FROM %s where "
+            "calendar_id IN (select id from %s where deleted = 0) "
+            "%s %s",
+            CAL_TABLE_TIMEZONE,
+            CAL_TABLE_CALENDAR,
+            limitquery,
+            offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+               *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_timezone._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_timezone_get_stmt(stmt,record);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    sqlite3_finalize(stmt);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_get_records_with_query( calendar_query_h query, int offset, int limit, calendar_list_h* out_list )
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+
+    que = (cal_query_s *)query;
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, CAL_TABLE_TIMEZONE);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", CAL_TABLE_TIMEZONE);
+    }
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s AND "
+                "calendar_id IN (select id from %s where deleted = 0)",
+                condition,
+                CAL_TABLE_CALENDAR);
+    }
+    else
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE "
+                "calendar_id IN (select id from %s where deleted = 0)",
+                CAL_TABLE_CALENDAR);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_timezone._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_timezone_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_timezone_get_stmt(stmt,record);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+static int __cal_db_timezone_insert_records(const calendar_list_h list, int** ids)
+{
+    calendar_record_h record;
+    int ret = 0;
+    int count = 0;
+    int i=0;
+    int *id = NULL;
+
+    ret = calendar_list_get_count(list, &count);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list get error");
+        return ret;
+    }
+
+    id = calloc(1, sizeof(int)*count);
+
+    retvm_if(NULL == id, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc fail");
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        CAL_FREE(id);
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_timezone_insert_record(record, &id[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                CAL_FREE(id);
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+        i++;
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    if(ids)
+    {
+        *ids = id;
+    }
+    else
+    {
+        CAL_FREE(id);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_update_records(const calendar_list_h list)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_timezone_update_record(record) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_delete_records(int ids[], int count)
+{
+    int i=0;
+    for(i=0;i<count;i++)
+    {
+        if (__cal_db_timezone_delete_record(ids[i]) != CALENDAR_ERROR_NONE)
+        {
+            ERR("delete failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_replace_records(const calendar_list_h list, int ids[], int count)
+{
+    calendar_record_h record;
+       int i;
+    int ret = 0;
+
+       if (NULL == list)
+       {
+               ERR("Invalid argument: list is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+
+       for (i = 0; i < count; i++)
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_timezone_replace_record(record, ids[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+               if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
+               {
+                       break;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s where "
+            "calendar_id IN (select id from %s where deleted = 0)",
+            CAL_TABLE_TIMEZONE,
+            CAL_TABLE_CALENDAR);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_timezone_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_TIMEZONE))
+    {
+        table_name = SAFE_STRDUP(CAL_TABLE_TIMEZONE);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s AND "
+                "calendar_id IN (select id from %s where deleted = 0)",
+                condition,
+                CAL_TABLE_CALENDAR);
+    }
+    else
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE "
+                "calendar_id IN (select id from %s where deleted = 0)",
+                CAL_TABLE_CALENDAR);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_timezone_get_stmt(sqlite3_stmt *stmt,calendar_record_h record)
+{
+    cal_timezone_s* timezone =  (cal_timezone_s*)(record);
+    int count = 0;
+    const unsigned char *temp;
+
+    timezone->index = sqlite3_column_int(stmt, count++);
+    timezone->tz_offset_from_gmt = sqlite3_column_int(stmt, count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    timezone->standard_name = SAFE_STRDUP(temp);
+
+    timezone->std_start_month = sqlite3_column_int(stmt, count++);
+    timezone->std_start_position_of_week = sqlite3_column_int(stmt, count++);
+    timezone->std_start_day = sqlite3_column_int(stmt, count++);
+    timezone->std_start_hour = sqlite3_column_int(stmt, count++);
+    timezone->standard_bias = sqlite3_column_int(stmt, count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    timezone->day_light_name = SAFE_STRDUP(temp);
+
+    timezone->day_light_start_month = sqlite3_column_int(stmt, count++);
+    timezone->day_light_start_position_of_week = sqlite3_column_int(stmt, count++);
+    timezone->day_light_start_day = sqlite3_column_int(stmt, count++);
+    timezone->day_light_start_hour = sqlite3_column_int(stmt, count++);
+    timezone->day_light_bias = sqlite3_column_int(stmt, count++);
+
+    timezone->calendar_id = sqlite3_column_int(stmt, count++);
+}
+
+static void __cal_db_timezone_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int stmt_count, calendar_record_h record)
+{
+    cal_timezone_s* timezone =  (cal_timezone_s*)(record);
+    const unsigned char *temp;
+
+    switch(property)
+    {
+    case CAL_PROPERTY_TIMEZONE_ID:
+        timezone->index = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_TZ_OFFSET_FROM_GMT:
+        timezone->tz_offset_from_gmt = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_STANDARD_NAME:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        timezone->standard_name = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TIMEZONE_STD_START_MONTH:
+        timezone->std_start_month = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_STD_START_POSITION_OF_WEEK:
+        timezone->std_start_position_of_week = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_STD_START_DAY:
+        timezone->std_start_day = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_STD_START_HOUR:
+        timezone->std_start_hour = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_STANDARD_BIAS:
+        timezone->standard_bias = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_NAME:
+        temp = sqlite3_column_text(stmt, stmt_count);
+        timezone->day_light_name = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_MONTH:
+        timezone->day_light_start_month = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_POSITION_OF_WEEK:
+        timezone->day_light_start_position_of_week = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_DAY:
+        timezone->day_light_start_day = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_START_HOUR:
+        timezone->day_light_start_hour = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_DAY_LIGHT_BIAS:
+        timezone->day_light_bias = sqlite3_column_int(stmt, stmt_count);
+        break;
+    case CAL_PROPERTY_TIMEZONE_CALENDAR_ID:
+        timezone->calendar_id = sqlite3_column_int(stmt, stmt_count);
+        break;
+    default:
+        sqlite3_column_int(stmt, stmt_count);
+        break;
+    }
+
+    return;
+}
+
+static void __cal_db_timezone_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_timezone_get_property_stmt(stmt,projection[i],i,record);
+    }
+}
+
+static int __cal_db_timezone_update_projection(calendar_record_h record)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_timezone_s* timezone =  (cal_timezone_s*)(record);
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int ret = CALENDAR_ERROR_NONE;
+    char* set = NULL;
+    GSList *bind_text = NULL;
+    int len;
+    GSList *cursor = NULL;
+
+    ret = _cal_db_query_create_projection_update_set(record,&set,&bind_text);
+    retv_if(CALENDAR_ERROR_NONE != ret, ret);
+
+    snprintf(query, sizeof(query), "UPDATE %s SET %s "
+            "WHERE id = %d",
+            CAL_TABLE_TIMEZONE,set,
+            timezone->index);
+
+    CAL_DBG("%s",query);
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    // bind
+    if (bind_text)
+    {
+        int i = 0;
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret)
+       {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+
+        CAL_FREE(set);
+        if(bind_text)
+        {
+            for (cursor=bind_text; cursor;cursor=cursor->next)
+            {
+                CAL_FREE(cursor->data);
+            }
+            g_slist_free(bind_text);
+        }
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    sqlite3_finalize(stmt);
+
+    CAL_FREE(set);
+    if(bind_text)
+    {
+        for (cursor=bind_text; cursor;cursor=cursor->next)
+        {
+            CAL_FREE(cursor->data);
+        }
+        g_slist_free(bind_text);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
diff --git a/native/cal_db_plugin_todo.c b/native/cal_db_plugin_todo.c
new file mode 100644 (file)
index 0000000..5849652
--- /dev/null
@@ -0,0 +1,2027 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "calendar_db.h"
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+#include "cal_db_rrule.h"
+#include "cal_db_alarm.h"
+#include "cal_db_attendee.h"
+#include "cal_db_extended.h"
+
+static int __cal_db_todo_insert_record(calendar_record_h record, int* id);
+static int __cal_db_todo_get_record(int id, calendar_record_h* out_record);
+static int __cal_db_todo_update_record(calendar_record_h record);
+static int __cal_db_todo_delete_record(int id);
+static int __cal_db_todo_get_all_records(int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_todo_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
+static int __cal_db_todo_insert_records(const calendar_list_h list, int** ids);
+static int __cal_db_todo_update_records(const calendar_list_h list);
+static int __cal_db_todo_delete_records(int ids[], int count);
+static int __cal_db_todo_get_count(int *out_count);
+static int __cal_db_todo_get_count_with_query(calendar_query_h query, int *out_count);
+static int __cal_db_todo_replace_record(calendar_record_h record, int id);
+static int __cal_db_todo_replace_records(const calendar_list_h list, int ids[], int count);
+
+/*
+ * static function
+ */
+static void __cal_db_todo_get_stmt(sqlite3_stmt *stmt,bool is_view_table,calendar_record_h record);
+static void __cal_db_todo_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record);
+static void __cal_db_todo_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record);
+static int __cal_db_todo_update_dirty(calendar_record_h record);
+
+cal_db_plugin_cb_s _cal_db_todo_plugin_cb = {
+    .is_query_only = false,
+    .insert_record = __cal_db_todo_insert_record,
+    .get_record = __cal_db_todo_get_record,
+    .update_record = __cal_db_todo_update_record,
+    .delete_record = __cal_db_todo_delete_record,
+    .get_all_records = __cal_db_todo_get_all_records,
+    .get_records_with_query = __cal_db_todo_get_records_with_query,
+    .insert_records = __cal_db_todo_insert_records,
+    .update_records = __cal_db_todo_update_records,
+    .delete_records = __cal_db_todo_delete_records,
+    .get_count=__cal_db_todo_get_count,
+    .get_count_with_query=__cal_db_todo_get_count_with_query,
+    .replace_record = __cal_db_todo_replace_record,
+    .replace_records = __cal_db_todo_replace_records
+};
+
+static int __cal_db_todo_insert_record(calendar_record_h record, int* id)
+{
+    int ret = -1;
+    int index = -1;
+    int input_ver;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char dtstart_datetime[32] = {0};
+    char dtend_datetime[32] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_todo_s* todo =  (cal_todo_s*)(record);
+       cal_rrule_s *rrule = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int tmp = 0;
+    int calendar_book_id = 0;
+    calendar_record_h record_calendar = NULL;
+    int has_alarm = 0;
+
+    retv_if(NULL == todo, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    ret = calendar_record_get_int(record,
+            _calendar_todo.calendar_book_id, &calendar_book_id);
+    DBG("calendar_book_id(%d)", calendar_book_id);
+
+    ret = calendar_db_get_record(_calendar_book._uri,
+            calendar_book_id, &record_calendar);
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "calendar_book_id is invalid");
+
+    calendar_record_destroy(record_calendar, true);
+
+    has_alarm = _cal_db_alarm_has_alarm(todo->alarm_list);
+    input_ver = _cal_db_util_get_next_ver();
+    ret = snprintf(query, sizeof(query),
+        "INSERT INTO %s ("
+            "type, "
+            "created_ver, changed_ver, "
+            "summary, description, location, categories,  "
+            "task_status, priority, "
+            "sensitivity, uid, "
+            "calendar_id, "
+            "latitude, longitude, "
+            "created_time, completed_time, progress, "
+            "dtstart_type, dtstart_utime, dtstart_datetime, dtstart_tzid, "
+            "dtend_type, dtend_utime, dtend_datetime, dtend_tzid, "
+            "last_mod, rrule_id, "
+            "has_alarm, updated, "
+            "sync_data1, sync_data2, sync_data3, sync_data4, "
+            "organizer_name, organizer_email, has_attendee"
+            ") VALUES ( "
+            "%d, "
+            "%d, %d, "
+            "?, ?, ?, ?, "
+            "%d, %d, "
+            "%d, ?, "
+            "%d, "
+            "%lf, %lf, "
+            "strftime('%%s', 'now'), %lld, %d, "
+            "%d, %lld, ?, ?, "
+            "%d, %lld, ?, ?, "
+            "strftime('%%s', 'now'), %d "
+            ", %d, %ld"
+            ", ?, ?, ?, ?"
+            ", ?, ?, %d"
+            ") ",
+            CAL_TABLE_SCHEDULE,
+            CAL_SCH_TYPE_TODO, /*event->cal_type,*/
+            input_ver, input_ver,
+            todo->todo_status, todo->priority,
+            todo->sensitivity,
+            todo->calendar_id,
+            todo->latitude, todo->longitude,
+            todo->completed_time, todo->progress,
+            todo->start.type, todo->start.type == CALENDAR_TIME_UTIME ? todo->start.time.utime : 0,
+            todo->due.type, todo->due.type == CALENDAR_TIME_UTIME ? todo->due.time.utime : 0,
+            todo->freq > 0 ? 1 : 0,
+            has_alarm,
+                       todo->updated,
+            todo->attendee_list ? 1 : 0);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    int count = 1;
+
+    if (todo->summary)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->summary);
+    count++;
+
+    if (todo->description)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->description);
+    count++;
+
+    if (todo->location)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->location);
+    count++;
+
+    if (todo->categories)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->categories);
+    count++;
+
+    if (todo->uid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->uid);
+    count++;
+
+       if (CALENDAR_TIME_LOCALTIME == todo->start.type)
+       {
+               snprintf(dtstart_datetime, sizeof(dtstart_datetime), "%04d%02d%02d",
+                               todo->start.time.date.year,
+                               todo->start.time.date.month,
+                               todo->start.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, count, dtstart_datetime);
+       }
+    count++;
+
+    if (todo->start_tzid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->start_tzid);
+    count++;
+
+       if (CALENDAR_TIME_LOCALTIME == todo->due.type)
+       {
+               snprintf(dtend_datetime, sizeof(dtend_datetime), "%04d%02d%02d",
+                               todo->due.time.date.year,
+                               todo->due.time.date.month,
+                               todo->due.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, count, dtend_datetime);
+       }
+    count++;
+
+    if (todo->due_tzid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->due_tzid);
+    count++;
+
+    if (todo->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data1);
+    count++;
+    if (todo->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data2);
+    count++;
+    if (todo->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data3);
+    count++;
+    if (todo->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data4);
+    count++;
+    if (todo->organizer_name)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->organizer_name);
+    count++;
+    if (todo->organizer_email)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->organizer_email);
+    count++;
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret)
+    {
+        sqlite3_finalize(stmt);
+        ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+    index = _cal_db_util_last_insert_id();
+    sqlite3_finalize(stmt);
+
+    calendar_record_get_int(record, _calendar_todo.id, &tmp);
+    _cal_record_set_int(record, _calendar_todo.id, index);
+    if (id)
+    {
+        *id = index;
+    }
+
+       _cal_db_rrule_get_rrule_from_todo(record, &rrule);
+    _cal_db_rrule_insert_record(index, rrule);
+
+       calendar_list_h list;
+       if (todo->alarm_list)
+       {
+               list = NULL;
+               DBG("insert alarm");
+               ret = _cal_db_alarm_convert_gtoh(todo->alarm_list, index, &list);
+               ret = calendar_db_insert_records(list, NULL, NULL);
+               ret = calendar_list_destroy(list, false);
+       }
+    if (todo->attendee_list)
+    {
+        list = NULL;
+        DBG("insert attendee");
+        ret = _cal_db_attendee_convert_gtoh(todo->attendee_list, index, &list);
+        ret = calendar_db_insert_records(list, NULL, NULL);
+        ret = calendar_list_destroy(list, false);
+    }
+
+    if (todo->extended_list)
+    {
+        DBG("insert extended");
+        list = NULL;
+        ret = _cal_db_extended_convert_gtoh(todo->extended_list, index, CALENDAR_RECORD_TYPE_TODO, &list);
+        ret = calendar_db_insert_records(list, NULL, NULL);
+        ret = calendar_list_destroy(list, false);
+    }
+    else
+    {
+        DBG("No extended");
+    }
+
+       CAL_FREE(rrule);
+    _cal_db_util_notify(CAL_NOTI_TYPE_TODO);
+
+    _cal_record_set_int(record, _calendar_todo.id, tmp);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_get_record(int id, calendar_record_h* out_record)
+{
+    char query[CAL_DB_SQL_MAX_LEN];
+    int rc = 0;
+    cal_todo_s *todo = NULL;
+       cal_rrule_s *rrule = NULL;
+    sqlite3_stmt *stmt = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    GList *alarm_list = NULL;
+    GList *attendee_list = NULL;
+    GList *extended_list = NULL;
+
+    rc = calendar_record_create( _calendar_todo._uri ,out_record);
+    if (rc != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_record_create(%d)", rc);
+           return CALENDAR_ERROR_OUT_OF_MEMORY;
+    }
+
+    todo =  (cal_todo_s*)(*out_record);
+
+    snprintf(query, sizeof(query), "SELECT * FROM %s "
+            "WHERE id=%d AND type = %d AND calendar_id IN "
+            "(select id from %s where deleted = 0)",
+            CAL_TABLE_SCHEDULE,
+            id, CALENDAR_BOOK_TYPE_TODO,
+            CAL_TABLE_CALENDAR);
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    dbret = _cal_db_util_stmt_step(stmt);
+       if (dbret != CAL_DB_ROW)
+       {
+               ERR("Failed to step stmt(%d)", dbret);
+               sqlite3_finalize(stmt);
+        calendar_record_destroy(*out_record, true);
+               *out_record = NULL;
+               switch (dbret)
+               {
+               case CAL_DB_DONE:
+                       ERR("Failed to find record(%d)", dbret);
+                       return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+    __cal_db_todo_get_stmt(stmt,false,*out_record);
+    sqlite3_finalize(stmt);
+    stmt = NULL;
+
+    if (_cal_db_rrule_get_rrule(todo->index, &rrule) == CALENDAR_ERROR_NONE)
+    {
+        _cal_db_rrule_set_rrule_to_todo(rrule, *out_record);
+        CAL_FREE(rrule);
+    }
+
+       _cal_db_alarm_get_records(todo->index, &alarm_list);
+       todo->alarm_list = alarm_list;
+
+    _cal_db_attendee_get_records(todo->index, &attendee_list);
+    todo->attendee_list = attendee_list;
+
+    _cal_db_extended_get_records(todo->index, CALENDAR_RECORD_TYPE_TODO, &extended_list);
+    todo->extended_list = extended_list;
+
+       todo->has_alarm = 0;
+    if (todo->alarm_list)
+    {
+        if (g_list_length(todo->alarm_list) != 0)
+        {
+            todo->has_alarm = 1;
+        }
+    }
+    todo->has_attendee = 0;
+    if (todo->attendee_list)
+    {
+        if (g_list_length(todo->attendee_list) != 0)
+        {
+           todo->has_attendee = 1;
+        }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_update_record(calendar_record_h record)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char dtstart_datetime[32] = {0};
+    char dtend_datetime[32] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_todo_s* todo =  (cal_todo_s*)(record);
+       cal_rrule_s *rrule = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int has_alarm = 0;
+
+    retv_if(NULL == todo, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    //if (CAL_SYNC_STATUS_UPDATED != todo->sync_status)
+    //  todo->sync_status = CAL_SYNC_STATUS_UPDATED;
+    if (todo->common.properties_flags != NULL)
+    {
+        return __cal_db_todo_update_dirty(record);
+    }
+
+    has_alarm = _cal_db_alarm_has_alarm(todo->alarm_list);
+    snprintf(query, sizeof(query), "UPDATE %s SET "
+            "changed_ver = %d,"
+            "type = %d,"
+            "summary = ?,"
+            "description = ?,"
+            "location = ?,"
+            "categories = ?,"
+            "task_status = %d,"
+            "priority = %d,"
+            "sensitivity = %d, "
+            "uid = ?, "
+            "calendar_id = %d, "
+            "latitude = %lf,"
+            "longitude = %lf,"
+            "completed_time = %lld,"
+            "progress = %d, "
+            "dtstart_type = %d, "
+            "dtstart_utime = %lld, "
+            "dtstart_datetime = ?, "
+            "dtstart_tzid = ?, "
+            "dtend_type = %d, "
+            "dtend_utime = %lld, "
+            "dtend_datetime = ?, "
+            "dtend_tzid = ?, "
+            "last_mod = strftime('%%s', 'now'), "
+            "has_alarm = %d, "
+            "updated = %ld, "
+            "sync_data1 = ?, "
+            "sync_data2 = ?, "
+            "sync_data3 = ?, "
+            "sync_data4 = ?, "
+            "organizer_name = ?, "
+            "organizer_email = ?, "
+            "has_attendee = %d "
+            "WHERE id = %d;",
+        CAL_TABLE_SCHEDULE,
+        _cal_db_util_get_next_ver(),
+        CAL_SCH_TYPE_TODO,/*todo->cal_type,*/
+        todo->todo_status,
+        todo->priority,
+        todo->sensitivity,
+        todo->calendar_id,
+        todo->latitude,
+        todo->longitude,
+        todo->completed_time,
+        todo->progress,
+        todo->start.type,
+        todo->start.type == CALENDAR_TIME_UTIME ? todo->start.time.utime : 0,
+        todo->due.type,
+        todo->due.type == CALENDAR_TIME_UTIME ? todo->due.time.utime : 0,
+        has_alarm,
+        todo->updated,
+        todo->attendee_list ? 1 : 0,
+        todo->index);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    int count = 1;
+
+    if (todo->summary)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->summary);
+    count++;
+
+    if (todo->description)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->description);
+    count++;
+
+    if (todo->location)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->location);
+    count++;
+
+    if (todo->categories)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->categories);
+    count++;
+
+    if (todo->uid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->uid);
+    count++;
+
+       if (CALENDAR_TIME_LOCALTIME == todo->start.type)
+       {
+               snprintf(dtstart_datetime, sizeof(dtstart_datetime), "%04d%02d%02d",
+                               todo->start.time.date.year,
+                               todo->start.time.date.month,
+                               todo->start.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, count, dtstart_datetime);
+       }
+    count++;
+
+    if (todo->start_tzid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->start_tzid);
+    count++;
+
+       if (CALENDAR_TIME_LOCALTIME == todo->due.type)
+       {
+               snprintf(dtend_datetime, sizeof(dtend_datetime), "%04d%02d%02d",
+                               todo->due.time.date.year,
+                               todo->due.time.date.month,
+                               todo->due.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, count, dtend_datetime);
+       }
+    count++;
+
+    if (todo->due_tzid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->due_tzid);
+    count++;
+
+    if (todo->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data1);
+    count++;
+    if (todo->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data2);
+    count++;
+    if (todo->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data3);
+    count++;
+    if (todo->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data4);
+    count++;
+    if (todo->organizer_name)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->organizer_name);
+    count++;
+    if (todo->organizer_email)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->organizer_email);
+    count++;
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret) {
+        sqlite3_finalize(stmt);
+        ERR("sqlite3_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+    sqlite3_finalize(stmt);
+
+       _cal_db_rrule_get_rrule_from_todo(record, &rrule);
+       _cal_db_rrule_update_record(todo->index, rrule);
+       CAL_FREE(rrule);
+
+    //_cal_db_instance_publish_record(record);
+
+    _cal_db_alarm_delete_with_id(todo->index);
+    _cal_db_attendee_delete_with_id(todo->index);
+    _cal_db_extended_delete_with_id(todo->index, CALENDAR_RECORD_TYPE_TODO);
+
+    calendar_list_h list;
+
+    list = NULL;
+    ret = _cal_db_alarm_convert_gtoh(todo->alarm_list,todo->index, &list);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+    }
+
+    list = NULL;
+    ret = _cal_db_attendee_convert_gtoh(todo->attendee_list,todo->index, &list);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+    }
+
+    if (todo->extended_list)
+    {
+        DBG("insert extended");
+        list = NULL;
+        ret = _cal_db_extended_convert_gtoh(todo->extended_list, todo->index, CALENDAR_RECORD_TYPE_TODO, &list);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            calendar_db_insert_records(list, NULL, NULL);
+            calendar_list_destroy(list, false);
+        }
+    }
+
+    _cal_db_util_notify(CAL_NOTI_TYPE_TODO);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_delete_record(int id)
+{
+    int ret;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int calendar_book_id;
+    int account_id;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    calendar_record_h record_todo;
+    calendar_record_h record_calendar;
+
+    retvm_if(id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid argument: id < 0");
+
+    ret = calendar_db_get_record(_calendar_todo._uri, id, &record_todo);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               DBG("calendar_db_get_record() failed");
+               return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
+       }
+    ret = calendar_record_get_int(record_todo,
+            _calendar_todo.calendar_book_id, &calendar_book_id);
+    DBG("calendar_book_id(%d)", calendar_book_id);
+
+    ret = calendar_db_get_record(_calendar_book._uri,
+            calendar_book_id, &record_calendar);
+    ret = calendar_record_get_int(record_calendar,
+            _calendar_book.account_id, &account_id);
+    DBG("account_id(%d)", account_id);
+
+    if (account_id == LOCAL_ACCOUNT_ID) {
+        DBG("insert deleted table");
+        snprintf(query, sizeof(query),
+                "INSERT INTO %s ( "
+                "schedule_id, schedule_type, "
+                "calendar_id, deleted_ver "
+                ") VALUES ( "
+                "%d, %d,"
+                "%d, %d )",
+                CAL_TABLE_DELETED,
+                id, CAL_RECORD_TYPE_TODO,
+                calendar_book_id, _cal_db_util_get_next_ver());
+        DBG("query[%s]", query);
+
+        dbret = _cal_db_util_query_exec(query);
+               if (CAL_DB_OK != dbret)
+        {
+            ERR("_cal_db_util_query_exec() Failed");
+            calendar_record_destroy(record_todo, true);
+            calendar_record_destroy(record_calendar, true);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+        }
+
+        DBG("delete event");
+        snprintf(query, sizeof(query),
+                "DELETE FROM %s "
+                "WHERE id = %d ",
+                CAL_TABLE_SCHEDULE,
+                id);
+        DBG("query[%s]", query);
+
+        dbret = _cal_db_util_query_exec(query);
+               if (CAL_DB_OK != dbret)
+        {
+            ERR("_cal_db_util_query_exec() Failed");
+            calendar_record_destroy(record_todo, true);
+            calendar_record_destroy(record_calendar, true);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+        }
+
+        DBG("attendee, alarm and rrule is deleted by trigger");
+
+    } else {
+        DBG("set is_delete");
+        snprintf(query, sizeof(query),
+                "UPDATE %s "
+                "SET is_deleted = 1, "
+                "changed_ver = %d, "
+                "last_mod = strftime('%%s','now') "
+                "WHERE id = %d ",
+                CAL_TABLE_SCHEDULE,
+                _cal_db_util_get_next_ver(),
+                id);
+
+        dbret = _cal_db_util_query_exec(query);
+        if (dbret != CAL_DB_OK)
+               {
+            ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+        }
+
+        DBG("attendee, alarm and rrule will be deleted by trigger after sync clean");
+    }
+
+    ret = calendar_record_destroy(record_todo, true);
+    ret = calendar_record_destroy(record_calendar, true);
+
+    _cal_db_util_notify(CAL_NOTI_TYPE_TODO);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_replace_record(calendar_record_h record, int id)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char dtstart_datetime[32] = {0};
+    char dtend_datetime[32] = {0};
+    sqlite3_stmt *stmt = NULL;
+    cal_todo_s* todo =  (cal_todo_s*)(record);
+       cal_rrule_s *rrule = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    int has_alarm = 0;
+
+    retv_if(NULL == todo, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    //if (CAL_SYNC_STATUS_UPDATED != todo->sync_status)
+    //  todo->sync_status = CAL_SYNC_STATUS_UPDATED;
+    if (todo->common.properties_flags != NULL)
+    {
+        return __cal_db_todo_update_dirty(record);
+    }
+
+    has_alarm = _cal_db_alarm_has_alarm(todo->alarm_list);
+    snprintf(query, sizeof(query), "UPDATE %s SET "
+            "changed_ver = %d,"
+            "type = %d,"
+            "summary = ?,"
+            "description = ?,"
+            "location = ?,"
+            "categories = ?,"
+            "task_status = %d,"
+            "priority = %d,"
+            "sensitivity = %d, "
+            "uid = ?, "
+            "calendar_id = %d, "
+            "latitude = %lf,"
+            "longitude = %lf,"
+            "completed_time = %lld,"
+            "progress = %d, "
+            "dtstart_type = %d, "
+            "dtstart_utime = %lld, "
+            "dtstart_datetime = ?, "
+            "dtstart_tzid = ?, "
+            "dtend_type = %d, "
+            "dtend_utime = %lld, "
+            "dtend_datetime = ?, "
+            "dtend_tzid = ?, "
+            "last_mod = strftime('%%s', 'now'), "
+            "has_alarm = %d, "
+            "updated = %ld, "
+            "sync_data1 = ?, "
+            "sync_data2 = ?, "
+            "sync_data3 = ?, "
+            "sync_data4 = ?, "
+            "organizer_name = ?, "
+            "organizer_email = ?, "
+            "has_attendee = %d "
+            "WHERE id = %d;",
+        CAL_TABLE_SCHEDULE,
+        _cal_db_util_get_next_ver(),
+        CAL_SCH_TYPE_TODO,/*todo->cal_type,*/
+        todo->todo_status,
+        todo->priority,
+        todo->sensitivity,
+        todo->calendar_id,
+        todo->latitude,
+        todo->longitude,
+        todo->completed_time,
+        todo->progress,
+        todo->start.type,
+        todo->start.type == CALENDAR_TIME_UTIME ? todo->start.time.utime : 0,
+        todo->due.type,
+        todo->due.type == CALENDAR_TIME_UTIME ? todo->due.time.utime : 0,
+        has_alarm,
+        todo->updated,
+        todo->attendee_list ? 1 : 0,
+        id);
+
+    stmt = _cal_db_util_query_prepare(query);
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, "_cal_db_util_query_prepare() Failed");
+
+    int count = 1;
+
+    if (todo->summary)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->summary);
+    count++;
+
+    if (todo->description)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->description);
+    count++;
+
+    if (todo->location)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->location);
+    count++;
+
+    if (todo->categories)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->categories);
+    count++;
+
+    if (todo->uid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->uid);
+    count++;
+
+       if (CALENDAR_TIME_LOCALTIME == todo->start.type)
+       {
+               snprintf(dtstart_datetime, sizeof(dtstart_datetime), "%04d%02d%02d",
+                               todo->start.time.date.year,
+                               todo->start.time.date.month,
+                               todo->start.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, count, dtstart_datetime);
+       }
+    count++;
+
+    if (todo->start_tzid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->start_tzid);
+    count++;
+
+       if (CALENDAR_TIME_LOCALTIME == todo->due.type)
+       {
+               snprintf(dtend_datetime, sizeof(dtend_datetime), "%04d%02d%02d",
+                               todo->due.time.date.year,
+                               todo->due.time.date.month,
+                               todo->due.time.date.mday);
+               _cal_db_util_stmt_bind_text(stmt, count, dtend_datetime);
+       }
+    count++;
+
+    if (todo->due_tzid)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->due_tzid);
+    count++;
+
+    if (todo->sync_data1)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data1);
+    count++;
+    if (todo->sync_data2)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data2);
+    count++;
+    if (todo->sync_data3)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data3);
+    count++;
+    if (todo->sync_data4)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->sync_data4);
+    count++;
+    if (todo->organizer_name)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->organizer_name);
+    count++;
+    if (todo->organizer_email)
+        _cal_db_util_stmt_bind_text(stmt, count, todo->organizer_email);
+    count++;
+
+    dbret = _cal_db_util_stmt_step(stmt);
+    if (CAL_DB_DONE != dbret) {
+        sqlite3_finalize(stmt);
+        ERR("sqlite3_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+    sqlite3_finalize(stmt);
+
+       _cal_db_rrule_get_rrule_from_todo(record, &rrule);
+       _cal_db_rrule_update_record(id, rrule);
+       CAL_FREE(rrule);
+
+    //_cal_db_instance_publish_record(record);
+
+    _cal_db_alarm_delete_with_id(id);
+    _cal_db_attendee_delete_with_id(id);
+    _cal_db_extended_delete_with_id(id, CALENDAR_RECORD_TYPE_TODO);
+
+    calendar_list_h list;
+
+    list = NULL;
+    ret = _cal_db_alarm_convert_gtoh(todo->alarm_list, id, &list);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+    }
+
+    list = NULL;
+    ret = _cal_db_attendee_convert_gtoh(todo->attendee_list, id, &list);
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        calendar_db_insert_records(list, NULL, NULL);
+        calendar_list_destroy(list, false);
+    }
+
+    if (todo->extended_list)
+    {
+        DBG("insert extended");
+        list = NULL;
+        ret = _cal_db_extended_convert_gtoh(todo->extended_list, id, CALENDAR_RECORD_TYPE_TODO, &list);
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            calendar_db_insert_records(list, NULL, NULL);
+            calendar_list_destroy(list, false);
+        }
+    }
+
+    _cal_db_util_notify(CAL_NOTI_TYPE_TODO);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_get_all_records(int offset, int limit, calendar_list_h* out_list)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
+    char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+    retvm_if(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    ret = calendar_list_create(out_list);
+
+    retvm_if(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    if (offset > 0)
+    {
+        snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
+    }
+    if (limit > 0)
+    {
+        snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
+    }
+    snprintf(query, sizeof(query), "SELECT * FROM %s %s %s", CAL_VIEW_TABLE_TODO,limitquery,offsetquery);
+
+    stmt = _cal_db_util_query_prepare(query);
+
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        calendar_list_destroy(*out_list, true);
+               *out_list = NULL;
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    retvm_if(NULL == stmt, CALENDAR_ERROR_DB_FAILED, );
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_todo._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        __cal_db_todo_get_stmt(stmt,true,record);
+
+        // child
+        int has_attendee = 0, has_alarm = 0;
+        int record_id = 0;
+        cal_todo_s* ptodo = (cal_todo_s*) record;
+        calendar_record_get_int(record, _calendar_todo.id, &record_id);
+        if(calendar_record_get_int(record, _calendar_todo.has_attendee,&has_attendee) == CALENDAR_ERROR_NONE)
+        {
+            if( has_attendee == 1)
+            {
+                _cal_db_attendee_get_records(record_id, &ptodo->attendee_list);
+            }
+        }
+        if(calendar_record_get_int(record, _calendar_todo.has_alarm,&has_alarm) == CALENDAR_ERROR_NONE)
+        {
+            if( has_alarm == 1)
+            {
+                _cal_db_alarm_get_records(record_id, &ptodo->alarm_list);
+            }
+        }
+
+        _cal_db_extended_get_records(record_id, CALENDAR_RECORD_TYPE_TODO, &ptodo->extended_list);
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char *projection = NULL;
+    char *order = NULL;
+    GSList *bind_text = NULL, *cursor = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    sqlite3_stmt *stmt = NULL;
+    int i = 0;
+    char *table_name;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_TODO))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_TODO);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_TODO_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_TODO_CALENDAR);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+        //table_name = SAFE_STRDUP(CAL_TABLE_NORMAL_INSTANCE);
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query,
+                &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // make projection
+    ret = _cal_db_query_create_projection(query, &projection);
+
+    // query - projection
+    if (projection)
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT %s FROM %s", projection, table_name);
+    }
+    else
+    {
+        len = snprintf(strquery, sizeof(strquery), "SELECT * FROM %s", table_name);
+    }
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // ORDER
+    ret = _cal_db_query_create_order(query, &order);
+    if (order)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " %s", order);
+    }
+
+    if (0 < limit)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " LIMIT %d", limit);
+        if (0 < offset)
+            len += snprintf(strquery+len, sizeof(strquery)-len, " OFFSET %d", offset);
+    }
+
+    // query
+    stmt = _cal_db_util_query_prepare(strquery);
+    if (NULL == stmt)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    CAL_DBG("%s",strquery);
+
+    // bind text
+    if (bind_text)
+    {
+        len = g_slist_length(bind_text);
+        for (cursor=bind_text, i=1; cursor;cursor=cursor->next, i++)
+        {
+            _cal_db_util_stmt_bind_text(stmt, i, cursor->data);
+        }
+    }
+
+    //
+    ret = calendar_list_create(out_list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+        ERR("calendar_list_create() Failed");
+        sqlite3_finalize(stmt);
+        return ret;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        calendar_record_h record;
+        // stmt -> record
+        ret = calendar_record_create(_calendar_todo._uri,&record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+        if (que->projection_count > 0)
+        {
+                       _cal_record_set_projection(record,
+                                       que->projection, que->projection_count, que->property_count);
+
+            __cal_db_todo_get_projection_stmt(stmt,
+                                       que->projection, que->projection_count,
+                    record);
+        }
+        else
+        {
+            __cal_db_todo_get_stmt(stmt,true,record);
+        }
+
+        // child
+        if (_cal_db_query_find_projection_property(query,CAL_PROPERTY_TODO_CALENDAR_ALARM) == true)
+        {
+            cal_todo_s* todo = (cal_todo_s*) record;
+            _cal_db_alarm_get_records(todo->index, &todo->alarm_list);
+        }
+        if (_cal_db_query_find_projection_property(query,CAL_PROPERTY_TODO_CALENDAR_ATTENDEE) == true)
+        {
+            cal_todo_s* todo = (cal_todo_s*) record;
+            _cal_db_attendee_get_records(todo->index, &todo->attendee_list);
+        }
+        if (_cal_db_query_find_projection_property(query,CAL_PROPERTY_TODO_EXTENDED) == true)
+        {
+            cal_todo_s* todo = (cal_todo_s*) record;
+            _cal_db_extended_get_records(todo->index, CALENDAR_RECORD_TYPE_TODO, &todo->extended_list);
+        }
+
+        ret = calendar_list_add(*out_list,record);
+        if( ret != CALENDAR_ERROR_NONE )
+        {
+            calendar_list_destroy(*out_list, true);
+                       *out_list = NULL;
+            calendar_record_destroy(record, true);
+
+            if (bind_text)
+            {
+                g_slist_free(bind_text);
+            }
+            CAL_FREE(condition);
+            CAL_FREE(projection);
+            sqlite3_finalize(stmt);
+            return ret;
+        }
+    }
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+    CAL_FREE(condition);
+    CAL_FREE(projection);
+
+    sqlite3_finalize(stmt);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_insert_records(const calendar_list_h list, int** ids)
+{
+    calendar_record_h record;
+    int ret = 0;
+    int count = 0;
+    int i=0;
+    int *id = NULL;
+
+    ret = calendar_list_get_count(list, &count);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list get error");
+        return ret;
+    }
+
+    id = calloc(1, sizeof(int)*count);
+
+    retvm_if(NULL == id, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc fail");
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        CAL_FREE(id);
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_todo_insert_record(record, &id[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                CAL_FREE(id);
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+        i++;
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    if(ids)
+    {
+        *ids = id;
+    }
+    else
+    {
+        CAL_FREE(id);
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_update_records(const calendar_list_h list)
+{
+    calendar_record_h record;
+    int ret = 0;
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+    do
+    {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_todo_update_record(record) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+    } while(calendar_list_next(list) != CALENDAR_ERROR_NO_DATA);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_delete_records(int ids[], int count)
+{
+    int i=0;
+    for(i=0;i<count;i++)
+    {
+        if (__cal_db_todo_delete_record(ids[i]) != CALENDAR_ERROR_NONE)
+        {
+            ERR("delete failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+    }
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_get_count(int *out_count)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    int count = 0;
+       int ret;
+
+    retvm_if(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER, "Invalid parameter");
+
+    snprintf(query, sizeof(query), "SELECT count(*) FROM %s ", CAL_VIEW_TABLE_TODO);
+
+    ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+    CAL_DBG("%s=%d",query,count);
+
+    *out_count = count;
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_todo_replace_records(const calendar_list_h list, int ids[], int count)
+{
+    calendar_record_h record;
+       int i = 0;
+    int ret = 0;
+
+       if (NULL == list)
+       {
+               ERR("Invalid argument: list is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    ret = calendar_list_first(list);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("list first error");
+        return ret;
+    }
+
+       for (i = 0; i < count; i++)
+       {
+        if( calendar_list_get_current_record_p(list, &record) == CALENDAR_ERROR_NONE)
+        {
+            if( __cal_db_todo_replace_record(record, ids[i]) != CALENDAR_ERROR_NONE)
+            {
+                ERR("db insert error");
+                return CALENDAR_ERROR_DB_FAILED;
+            }
+        }
+               if (CALENDAR_ERROR_NO_DATA != calendar_list_next(list))
+               {
+                       break;
+               }
+    }
+
+    return CALENDAR_ERROR_NONE;
+}
+
+
+static int __cal_db_todo_get_count_with_query(calendar_query_h query, int *out_count)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    char *condition = NULL;
+    char strquery[CAL_DB_SQL_MAX_LEN] = {0};
+    int len;
+    char *table_name;
+    int count = 0;
+    GSList *bind_text = NULL;
+
+    que = (cal_query_s *)query;
+
+    if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_TODO))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_TODO);
+    }
+    else if ( 0 == strcmp(que->view_uri, CALENDAR_VIEW_TODO_CALENDAR))
+    {
+        table_name = SAFE_STRDUP(CAL_VIEW_TABLE_TODO_CALENDAR);
+    }
+    else
+    {
+        ERR("uri(%s) not support get records with query",que->view_uri);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // make filter
+    if (que->filter)
+    {
+        ret = _cal_db_query_create_condition(query, &condition, &bind_text);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            CAL_FREE(table_name);
+            ERR("filter create fail");
+            return ret;
+        }
+    }
+
+    // query - select from
+
+    len = snprintf(strquery, sizeof(strquery), "SELECT count(*) FROM %s", table_name);
+    CAL_FREE(table_name);
+
+    // query - condition
+    if (condition)
+    {
+        len += snprintf(strquery+len, sizeof(strquery)-len, " WHERE %s", condition);
+    }
+
+    // query
+    ret = _cal_db_util_query_get_first_int_result(strquery, bind_text, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               if (bind_text)
+               {
+                       g_slist_free(bind_text);
+               }
+               CAL_FREE(condition);
+               return ret;
+       }
+    CAL_DBG("%s=%d",strquery,count);
+
+    *out_count = count;
+
+    if (bind_text)
+    {
+        g_slist_free(bind_text);
+    }
+       CAL_FREE(condition);
+    return CALENDAR_ERROR_NONE;
+}
+
+static void __cal_db_todo_get_stmt(sqlite3_stmt *stmt,bool is_view_table,calendar_record_h record)
+{
+    cal_todo_s *todo = NULL;
+    const unsigned char *temp;
+    int count = 0;
+    char *dtstart_datetime;
+    char *dtend_datetime;
+    char buf[8] = {0};
+
+    todo = (cal_todo_s*)(record);
+
+    todo->index = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//todo->account_id = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//todo->cal_type = 1;/*sqlite3_column_int(stmt, count++);*/
+
+    temp = sqlite3_column_text(stmt, count++);
+    todo->summary = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    todo->description = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    todo->location = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    todo->categories = SAFE_STRDUP(temp);
+
+    sqlite3_column_text(stmt, count++);
+    //todo->exdate = SAFE_STRDUP(temp);
+
+    todo->todo_status = sqlite3_column_int(stmt, count++);
+    todo->priority = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//todo->timezone = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//todo->contact_id = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//todo->busy_status = sqlite3_column_int(stmt, count++);
+    todo->sensitivity = sqlite3_column_int(stmt, count++);
+
+    temp = sqlite3_column_text(stmt, count++);
+    todo->uid = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    todo->organizer_name = SAFE_STRDUP(temp);
+
+    temp = sqlite3_column_text(stmt, count++);
+    todo->organizer_email = SAFE_STRDUP(temp);
+
+    sqlite3_column_int(stmt, count++);//todo->meeting_status = sqlite3_column_int(stmt, count++);
+
+    todo->calendar_id = sqlite3_column_int(stmt, count++);
+
+    sqlite3_column_int(stmt, count++);//todo->original_todo_id = sqlite3_column_int(stmt, count++);
+
+    todo->latitude = sqlite3_column_double(stmt,count++);
+    todo->longitude = sqlite3_column_double(stmt,count++);
+    sqlite3_column_int(stmt, count++);//todo->email_id = sqlite3_column_int(stmt, count++);
+    sqlite3_column_int(stmt, count++);//todo->availability = sqlite3_column_int(stmt, count++);
+
+    todo->created_time = sqlite3_column_int64(stmt, count++);
+
+    todo->completed_time = sqlite3_column_int64(stmt, count++);
+
+    todo->progress = sqlite3_column_int(stmt,count++);
+
+    sqlite3_column_int(stmt,count++);   //__version
+    sqlite3_column_int(stmt,count++);   //__version
+    todo->is_deleted = sqlite3_column_int(stmt,count++);
+
+    todo->start.type = sqlite3_column_int(stmt,count++);
+
+    if (todo->start.type == CALENDAR_TIME_UTIME)
+    {
+        todo->start.time.utime = sqlite3_column_int64(stmt,count++);
+        sqlite3_column_text(stmt, count++); // dtstart_datetime
+    }
+    else
+    {
+        sqlite3_column_int64(stmt,count++); //todo->start.time.utime = sqlite3_column_int64(stmt,count++);
+        temp = sqlite3_column_text(stmt, count++);
+        if (temp) {
+            dtstart_datetime = SAFE_STRDUP(temp);
+            snprintf(buf, strlen("YYYY") + 1, "%s", &dtstart_datetime[0]);
+            todo->start.time.date.year =  atoi(buf);
+            snprintf(buf, strlen("MM") + 1, "%s", &dtstart_datetime[4]);
+            todo->start.time.date.month = atoi(buf);
+            snprintf(buf, strlen("DD") + 1, "%s", &dtstart_datetime[6]);
+            todo->start.time.date.mday = atoi(buf);
+            if (dtstart_datetime) free(dtstart_datetime);
+        }
+    }
+
+    temp = sqlite3_column_text(stmt, count++);
+    todo->start_tzid = SAFE_STRDUP(temp);
+    todo->due.type = sqlite3_column_int(stmt, count++);
+    if (todo->due.type == CALENDAR_TIME_UTIME)
+    {
+        todo->due.time.utime = sqlite3_column_int64(stmt,count++);
+        sqlite3_column_text(stmt, count++); // dtdue_datetime
+    }
+    else
+    {
+        sqlite3_column_int64(stmt, count++);//todo->due.time.utime = sqlite3_column_int64(stmt, count++);
+        temp = sqlite3_column_text(stmt, count++);
+        if (temp) {
+            dtend_datetime = SAFE_STRDUP(temp);
+            snprintf(buf, strlen("YYYY") + 1, "%s", &dtend_datetime[0]);
+            todo->due.time.date.year =  atoi(buf);
+            snprintf(buf, strlen("MM") + 1, "%s", &dtend_datetime[4]);
+            todo->due.time.date.month = atoi(buf);
+            snprintf(buf, strlen("DD") + 1, "%s", &dtend_datetime[6]);
+            todo->due.time.date.mday = atoi(buf);
+            if (dtend_datetime) free(dtend_datetime);
+        }
+    }
+    temp = sqlite3_column_text(stmt, count++);
+    todo->due_tzid = SAFE_STRDUP(temp);
+
+    todo->last_mod = sqlite3_column_int64(stmt,count++);
+    sqlite3_column_int(stmt,count++);//todo->rrule_id = sqlite3_column_int(stmt,count++);
+
+    sqlite3_column_text(stmt, count++);
+    //todo->recurrence_id = SAFE_STRDUP(temp);
+    sqlite3_column_text(stmt, count++);
+    //todo->rdate = SAFE_STRDUP(temp);
+    todo->has_attendee = sqlite3_column_int(stmt,count++);
+    todo->has_alarm = sqlite3_column_int(stmt,count++);
+    sqlite3_column_int(stmt,count++); // system_type...
+    todo->updated = sqlite3_column_int(stmt,count++);
+    temp = sqlite3_column_text(stmt, count++);
+    todo->sync_data1 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    todo->sync_data2 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    todo->sync_data3 = SAFE_STRDUP(temp);
+    temp = sqlite3_column_text(stmt, count++);
+    todo->sync_data4 = SAFE_STRDUP(temp);
+
+    if (is_view_table == true)
+    {
+        todo->freq = sqlite3_column_int(stmt, count++);
+
+        if (todo->freq <= 0) {
+            //todo->rrule_id = 0;
+            //sqlite3_finalize(stmt);
+            //return CALENDAR_ERROR_NONE;
+            return ;
+        }
+
+        //todo->rrule_id = 1;
+        todo->range_type = sqlite3_column_int(stmt, count++);
+        todo->until_type = sqlite3_column_int(stmt, count++);
+        todo->until_utime = sqlite3_column_int64(stmt, count++);
+
+        temp = sqlite3_column_text(stmt, count++);
+               if (CALENDAR_TIME_LOCALTIME == todo->until_type)
+               {
+                       sscanf((const char *)temp, "%04d%02d%02d",
+                                       &todo->until_year, &todo->until_month, &todo->until_mday);
+               }
+
+        todo->count = sqlite3_column_int(stmt, count++);
+        todo->interval = sqlite3_column_int(stmt, count++);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->bysecond = SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->byminute = SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->byhour = SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->byday= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->bymonthday= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->byyearday= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->byweekno= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->bymonth= SAFE_STRDUP(temp);
+
+        temp = sqlite3_column_text(stmt, count++);
+        todo->bysetpos = SAFE_STRDUP(temp);
+
+        todo->wkst = sqlite3_column_int(stmt, count++);
+
+        sqlite3_column_int(stmt, count++); //calendar deleted
+    }
+}
+
+static void __cal_db_todo_get_property_stmt(sqlite3_stmt *stmt,
+        unsigned int property, int *stmt_count, calendar_record_h record)
+{
+    cal_todo_s *todo = NULL;
+    const unsigned char *temp;
+    char *dtstart_datetime;
+    char *dtend_datetime;
+    char buf[8] = {0};
+
+    todo = (cal_todo_s*)(record);
+
+    switch(property)
+    {
+    case CAL_PROPERTY_TODO_ID:
+        todo->index = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_CALENDAR_ID:
+        todo->calendar_id = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_SUMMARY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->summary = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_DESCRIPTION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->description = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_LOCATION:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->location = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_CATEGORIES:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->categories = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_TODO_STATUS:
+        todo->todo_status = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_PRIORITY:
+        todo->priority = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_SENSITIVITY:
+        todo->sensitivity = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_UID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->uid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_LATITUDE:
+        todo->latitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_LONGITUDE:
+        todo->longitude = sqlite3_column_double(stmt,*stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_PROGRESS:
+        todo->progress = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_COMPLETED_TIME:
+        todo->completed_time = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_CREATED_TIME:
+        todo->created_time = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_LAST_MODIFIED_TIME:
+        todo->last_mod = sqlite3_column_int64(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_IS_DELETED:
+        todo->is_deleted = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_FREQ:
+        todo->freq = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_RANGE_TYPE:
+        todo->range_type = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_UNTIL:
+        //!!
+        break;
+    case CAL_PROPERTY_TODO_COUNT:
+        todo->count = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_INTERVAL:
+        todo->interval = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_BYSECOND:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->bysecond = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYMINUTE:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->byminute = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYHOUR:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->byhour = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYDAY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->byday = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTHDAY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->bymonthday = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYYEARDAY:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->byyearday = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYWEEKNO:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->byweekno = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYMONTH:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->bymonth = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_BYSETPOS:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->bysetpos = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_WKST:
+        todo->wkst = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_HAS_ALARM:
+        todo->has_alarm = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA1:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->sync_data1 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA2:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->sync_data2 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA3:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->sync_data3 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_SYNC_DATA4:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->sync_data4 = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_START:
+        //!!
+        todo->start.type = sqlite3_column_int(stmt,*stmt_count);
+        if (todo->start.type == CALENDAR_TIME_UTIME)
+        {
+            *stmt_count = *stmt_count+1;
+            todo->start.time.utime = sqlite3_column_int64(stmt,*stmt_count);
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_text(stmt, *stmt_count);
+        }
+        else
+        {
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_int64(stmt,*stmt_count); //todo->start.time.utime = sqlite3_column_int64(stmt,count++);
+            *stmt_count = *stmt_count+1;
+            temp = sqlite3_column_text(stmt, *stmt_count);
+            if (temp) {
+                dtstart_datetime = SAFE_STRDUP(temp);
+                snprintf(buf, strlen("YYYY") + 1, "%s", &dtstart_datetime[0]);
+                todo->start.time.date.year =  atoi(buf);
+                snprintf(buf, strlen("MM") + 1, "%s", &dtstart_datetime[4]);
+                todo->start.time.date.month = atoi(buf);
+                snprintf(buf, strlen("DD") + 1, "%s", &dtstart_datetime[6]);
+                todo->start.time.date.mday = atoi(buf);
+                if (dtstart_datetime) free(dtstart_datetime);
+            }
+        }
+        break;
+    case CAL_PROPERTY_TODO_START_TZID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->start_tzid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_DUE:
+        //!!
+        todo->due.type = sqlite3_column_int(stmt, *stmt_count);
+        if (todo->due.type == CALENDAR_TIME_UTIME)
+        {
+            *stmt_count = *stmt_count+1;
+            todo->due.time.utime = sqlite3_column_int64(stmt,*stmt_count);
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_text(stmt, *stmt_count);
+        }
+        else
+        {
+            *stmt_count = *stmt_count+1;
+            sqlite3_column_int64(stmt, *stmt_count);//todo->due.time.utime = sqlite3_column_int64(stmt, count++);
+            *stmt_count = *stmt_count+1;
+            temp = sqlite3_column_text(stmt, *stmt_count);
+            if (temp) {
+                dtend_datetime = SAFE_STRDUP(temp);
+                snprintf(buf, strlen("YYYY") + 1, "%s", &dtend_datetime[0]);
+                todo->due.time.date.year =  atoi(buf);
+                snprintf(buf, strlen("MM") + 1, "%s", &dtend_datetime[4]);
+                todo->due.time.date.month = atoi(buf);
+                snprintf(buf, strlen("DD") + 1, "%s", &dtend_datetime[6]);
+                todo->due.time.date.mday = atoi(buf);
+                if (dtend_datetime) free(dtend_datetime);
+            }
+        }
+        break;
+    case CAL_PROPERTY_TODO_DUE_TZID:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->due_tzid = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_NAME:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->organizer_name = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_ORGANIZER_EMAIL:
+        temp = sqlite3_column_text(stmt, *stmt_count);
+        todo->organizer_email = SAFE_STRDUP(temp);
+        break;
+    case CAL_PROPERTY_TODO_HAS_ATTENDEE:
+        todo->has_attendee = sqlite3_column_int(stmt, *stmt_count);
+        break;
+    default:
+        sqlite3_column_int(stmt, *stmt_count);
+        break;
+    }
+
+    *stmt_count = *stmt_count+1;
+}
+
+static void __cal_db_todo_get_projection_stmt(sqlite3_stmt *stmt,
+        const unsigned int *projection, const int projection_count,
+        calendar_record_h record)
+{
+    int i=0;
+    int stmt_count = 0;
+
+    for(i=0;i<projection_count;i++)
+    {
+        __cal_db_todo_get_property_stmt(stmt,projection[i],&stmt_count,record);
+    }
+}
+
+static int __cal_db_todo_update_dirty(calendar_record_h record)
+{
+    int todo_id = 0;
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_record_h original_record;
+
+    ret = calendar_record_get_int(record,_calendar_todo.id, &todo_id);
+    retv_if(CALENDAR_ERROR_NONE != ret, ret);
+
+    CAL_DBG("id=%d",todo_id);
+
+    ret = __cal_db_todo_get_record(todo_id, &original_record);
+
+    if (ret == CALENDAR_ERROR_NONE)
+    {
+        cal_record_s *_record = NULL;
+        const cal_property_info_s* property_info = NULL;
+        int property_info_count = 0;
+        int i=0;
+
+        _record = (cal_record_s *)record;
+
+        property_info = _cal_view_get_property_info(_record->view_uri, &property_info_count);
+
+        for(i=0;i<property_info_count;i++)
+        {
+            if (true == _cal_record_check_property_flag(record, property_info[i].property_id , CAL_PROPERTY_FLAG_DIRTY))
+            {
+                if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_INT) == true)
+                {
+                    int tmp=0;
+                    ret = calendar_record_get_int(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_int(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_STR) == true)
+                {
+                    char *tmp=NULL;
+                    ret = calendar_record_get_str_p(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_str(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+                {
+                    double tmp=0;
+                    ret = calendar_record_get_double(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_double(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_LLI) == true)
+                {
+                    long long int tmp=0;
+                    ret = calendar_record_get_lli(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_lli(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+                else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+                {
+                    calendar_time_s tmp = {0,};
+                    ret = calendar_record_get_caltime(record,property_info[i].property_id,&tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                    ret = _cal_record_set_caltime(original_record, property_info[i].property_id, tmp);
+                    if (ret != CALENDAR_ERROR_NONE)
+                        continue;
+                }
+            }
+        }
+
+        // child replace
+        // alarm
+        cal_todo_s *tmp = (cal_todo_s *)original_record;
+        cal_todo_s *tmp_src = (cal_todo_s *)record;
+        if ( tmp->alarm_list )
+        {
+            GList *alarm_list = g_list_first(tmp->alarm_list);
+            calendar_record_h alarm_child_record = NULL;
+            while (alarm_list)
+            {
+                alarm_child_record = (calendar_record_h)alarm_list->data;
+                if (alarm_child_record == NULL)
+                {
+                    alarm_list = g_list_next(alarm_list);
+                    continue;
+                }
+
+                calendar_record_destroy(alarm_child_record, true);
+
+                alarm_list = g_list_next(alarm_list);
+            }
+            g_list_free(tmp->alarm_list);
+        }
+        tmp->alarm_list = tmp_src->alarm_list;
+
+        if( tmp->attendee_list )
+        {
+            GList * attendee_list = g_list_first(tmp->attendee_list);
+            calendar_record_h attendee = NULL;
+
+            while (attendee_list)
+            {
+                attendee = (calendar_record_h)attendee_list->data;
+                if (attendee == NULL)
+                {
+                    attendee_list = g_list_next(attendee_list);
+                    continue;
+                }
+
+                calendar_record_destroy(attendee, true);
+
+                attendee_list = g_list_next(attendee_list);
+            }
+            g_list_free(tmp->attendee_list);
+        }
+        tmp->attendee_list = tmp_src->attendee_list;
+        if( tmp->extended_list )
+        {
+            GList * extended_list = g_list_first(tmp->extended_list);
+            calendar_record_h extended = NULL;
+
+            while (extended_list)
+            {
+                extended = (calendar_record_h)extended_list->data;
+                if (extended == NULL)
+                {
+                    extended_list = g_list_next(extended_list);
+                    continue;
+                }
+
+                calendar_record_destroy(extended, true);
+
+                extended_list = g_list_next(extended_list);
+            }
+            g_list_free(tmp->extended_list);
+        }
+        tmp->extended_list = tmp_src->extended_list;
+    }
+    else
+    {
+        CAL_DBG("get_record fail");
+        return ret;
+    }
+
+    CAL_RECORD_RESET_COMMON((cal_record_s*)original_record);
+    ret = __cal_db_todo_update_record(original_record);
+
+    calendar_record_destroy(original_record,false);
+
+    return ret;
+}
diff --git a/native/cal_db_query.c b/native/cal_db_query.c
new file mode 100644 (file)
index 0000000..39664f7
--- /dev/null
@@ -0,0 +1,982 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+
+#define CAL_DB_CALTIME_FIELD_MAX 3
+
+static const char* __cal_db_utime_field_name[] =
+{
+        "dtstart_utime",
+        "dtend_utime",
+        "until_utime"
+};
+static const char* __cal_db_datetime_field_name[] =
+{
+        "dtstart_datetime",
+        "dtend_datetime",
+        "until_datetime"
+};
+static const char* __cal_db_timetype_field_name[] =
+{
+        "dtstart_type",
+        "dtend_type",
+        "until_type"
+};
+
+static int __cal_db_query_create_composite_condition(cal_composite_filter_s *com_filter,
+        char **condition, GSList **bind_text);
+static int __cal_db_query_create_attribute_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition, GSList **bind_text);
+static int __cal_db_query_create_str_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition, GSList **bind_text);
+static int __cal_db_query_create_int_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition );
+static int __cal_db_query_create_double_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition );
+static int __cal_db_query_create_lli_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition );
+static int __cal_db_query_create_caltime_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition );
+static const char * __cal_db_query_get_property_field_name(const cal_property_info_s *properties,
+        int count, unsigned int property_id);
+static const char * __cal_db_query_get_utime_field_name(const char* src);
+static const char * __cal_db_query_get_datetime_field_name(const char* src);
+static const char * __cal_db_query_get_timetype_field_name(const char* src);
+
+int _cal_db_query_create_condition(calendar_query_h query, char **condition, GSList **bind_text)
+{
+    cal_query_s *que = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(NULL == query || NULL == condition || NULL == bind_text, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    que = (cal_query_s *)query;
+
+    ret = __cal_db_query_create_composite_condition(que->filter, condition, bind_text);
+
+    return ret;
+}
+
+int _cal_db_query_create_projection(calendar_query_h query, char **projection)
+{
+    int i = 0;
+    int len = 0;
+    const char *field_name;
+    char out_projection[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_query_s *query_s = NULL;
+    cal_property_info_s *properties = NULL;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    query_s = (cal_query_s *)query;
+
+    properties = query_s->properties;
+
+    if (query_s->projection)
+    {
+        field_name = __cal_db_query_get_property_field_name(properties, query_s->property_count, query_s->projection[0]);
+        if (field_name)
+            len += snprintf(out_projection+len, sizeof(out_projection)-len, "%s", field_name);
+
+        for (i=1;i<query_s->projection_count;i++)
+        {
+            field_name = __cal_db_query_get_property_field_name(properties, query_s->property_count, query_s->projection[i]);
+            if (field_name)
+                len += snprintf(out_projection+len, sizeof(out_projection)-len, ", %s", field_name);
+        }
+    }
+    else
+    {
+#if 0  // projection이 없을 경우 select *
+        for (i=1;i<query_s->property_count;i++) {
+            if (properties[i].fields)
+                len += snprintf(out_projection+len, sizeof(out_projection)-len, ", %s", (char *)properties[i].fields);
+            else
+                len += snprintf(out_projection+len, sizeof(out_projection)-len, ", %s", ctsvc_get_display_column());
+        }
+#endif
+        len += snprintf(out_projection+len, sizeof(out_projection)-len, " * ");
+    }
+
+       *projection = strdup(out_projection);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_query_create_order(calendar_query_h query, char **order)
+{
+    int len = 0;
+    const char *field_name;
+    char out_order[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_query_s *query_s = NULL;
+    cal_property_info_s *properties = NULL;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    query_s = (cal_query_s *)query;
+    properties = query_s->properties;
+
+    if (query_s->sort_property_id > 0)
+    {
+
+        field_name = __cal_db_query_get_property_field_name(properties, query_s->property_count, query_s->sort_property_id);
+
+        if (CAL_PROPERTY_CHECK_DATA_TYPE(query_s->sort_property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true && field_name)
+        {
+            const char *tmp = NULL;
+
+            if (strcmp(query_s->view_uri, CALENDAR_VIEW_INSTANCE_ALLDAY) == 0 ||
+                    strcmp(query_s->view_uri, CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR) == 0)
+            {
+                if(CAL_PROPERTY_INSTANCE_ALLDAY_START)
+                {
+                    tmp = __cal_db_datetime_field_name[0];
+                }
+                else
+                {
+                    tmp = __cal_db_datetime_field_name[1];
+                }
+                if (tmp != NULL)
+                {
+                     field_name = tmp;
+                }
+            }
+            else
+            {
+                tmp = __cal_db_query_get_utime_field_name(field_name);
+                if (tmp == NULL)
+                {
+                    tmp = __cal_db_query_get_datetime_field_name(field_name);
+                }
+                if (tmp != NULL)
+                {
+                     field_name = tmp;
+                }
+            }
+        }
+
+        if (field_name)
+            len += snprintf(out_order+len, sizeof(out_order)-len, "ORDER BY %s", field_name);
+    }
+    else
+    {
+        return CALENDAR_ERROR_NO_DATA;
+    }
+
+    if (field_name)
+    {
+        if (query_s->asc == false)
+        {
+            len += snprintf(out_order+len, sizeof(out_order)-len, " DESC");
+        }
+    #if 0    // is default
+        else // (query_s->asc == true)
+        {
+            len += snprintf(out_order+len, sizeof(out_order)-len, " ASC");
+        }
+    #endif
+    }
+
+       *order = strdup(out_order);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+bool _cal_db_query_find_projection_property(calendar_query_h query, unsigned int property)
+{
+    int i = 0;
+    cal_query_s *query_s = NULL;
+    cal_property_info_s *properties = NULL;
+
+    retv_if(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
+    query_s = (cal_query_s *)query;
+
+    properties = query_s->properties;
+
+    if (query_s->projection)
+    {
+        for (i=0;i<query_s->projection_count;i++)
+        {
+            if (query_s->projection[i] == property)
+            {
+                return true;
+            }
+        }
+    }
+    else
+    {
+        // projection
+        return true;
+    }
+
+    return false;
+}
+
+int _cal_db_query_create_projection_update_set(calendar_record_h record, char **set, GSList **bind_text)
+{
+    cal_record_s *_record = NULL;
+    int i = 0;
+    const cal_property_info_s* property_info = NULL;
+    int property_info_count = 0;
+    char out_set[CAL_DB_SQL_MAX_LEN] = {0};
+    int len = 0;
+    const char *field_name;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(record == NULL, -1);
+
+    _record = (cal_record_s *)record;
+
+    if (_record->properties_max_count == 0 || _record->properties_flags == NULL)
+    {
+        CAL_DBG("record don't have properties");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    // uri를 통해, property_info_s 가져옴
+    property_info = _cal_view_get_property_info(_record->view_uri, &property_info_count);
+
+    for(i=0;i<property_info_count;i++)
+    {
+        if (true == _cal_record_check_property_flag(record, property_info[i].property_id , CAL_PROPERTY_FLAG_DIRTY) )
+        {
+            field_name = property_info[i].fields;
+
+            if (field_name == NULL)
+            {
+                continue;
+            }
+
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_INT) == true)
+            {
+                int tmp=0;
+                ret = calendar_record_get_int(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d",field_name,tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_STR) == true)
+            {
+                char *tmp=NULL;
+                ret = calendar_record_get_str(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=?",field_name);
+                *bind_text = g_slist_append(*bind_text, tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+            {
+                double tmp=0;
+                ret = calendar_record_get_double(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%lf",field_name,tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_LLI) == true)
+            {
+                long long int tmp=0;
+                ret = calendar_record_get_lli(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%lld",field_name,tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+            {
+                /*
+                 * field_name
+                 * dtstart_type, dtstart_utime, dtstart_datetime
+                 *      -> dtstart_type=%d, dtstart_utime=%lli, dtstart_datetime=?
+                 * dtend_type, dtend_utime, dtend_datetime
+                 *      -> dtend_type=%d, dtend_utime=%lli, dtend_datetime=?
+                 * until_type, until_utime, until_datetime
+                 *      -> until_type=%d, until_utime=%lli, until_datetime=?
+                 */
+                calendar_time_s tmp = {0,};
+                const char *timetype_field = NULL;
+                const char *utime_field = NULL;
+                const char *datetime_field = NULL;
+                timetype_field = __cal_db_query_get_timetype_field_name(field_name);
+                utime_field = __cal_db_query_get_utime_field_name(field_name);
+                datetime_field = __cal_db_query_get_datetime_field_name(field_name);
+                ret = calendar_record_get_caltime(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if(tmp.type == CALENDAR_TIME_UTIME)
+                {
+                    if (strlen(out_set) != 0)
+                    {
+                        len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                    }
+                    len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d, %s=%lld",
+                            timetype_field, CALENDAR_TIME_UTIME, utime_field, tmp.time.utime);
+                }
+                else
+                {
+                    char *bind_tmp = NULL;
+                    char bind_datetime[32] = {0};
+                    snprintf(bind_datetime, sizeof(bind_datetime), "%04d%02d%02d",
+                            tmp.time.date.year,
+                            tmp.time.date.month,
+                            tmp.time.date.mday);
+
+                    if (strlen(out_set) != 0)
+                    {
+                        len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                    }
+                    len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d, %s=?",
+                                                       timetype_field, CALENDAR_TIME_LOCALTIME, datetime_field);
+
+                    bind_tmp= strdup(bind_datetime);
+                    *bind_text = g_slist_append(*bind_text, bind_tmp);
+                }
+            }
+        }
+    }
+
+    *set = strdup(out_set);
+    CAL_DBG("set=%s",*set);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_query_create_projection_update_set_with_property(
+        calendar_record_h record, unsigned int *properties, int properties_count,
+        char **set, GSList **bind_text)
+{
+    cal_record_s *_record = NULL;
+    int i = 0;
+    const cal_property_info_s* property_info = NULL;
+    int property_info_count = 0;
+    char out_set[CAL_DB_SQL_MAX_LEN] = {0};
+    int len = 0;
+    const char *field_name;
+    int ret = CALENDAR_ERROR_NONE;
+
+    retv_if(record == NULL, -1);
+
+    _record = (cal_record_s *)record;
+
+    if (_record->properties_max_count == 0 || _record->properties_flags == NULL)
+    {
+        return CALENDAR_ERROR_NONE;
+    }
+
+    // uri를 통해, property_info_s 가져옴
+    property_info = _cal_view_get_property_info(_record->view_uri, &property_info_count);
+
+    for(i=0;i<property_info_count;i++)
+    {
+        int j=0;
+        bool flag = false;
+        for(j=0;j<properties_count;j++)
+        {
+            if( property_info[i].property_id == properties[j] )
+            {
+                flag = true;
+                break;
+            }
+        }
+        if (true == flag &&
+                ( true == _cal_record_check_property_flag(record, property_info[i].property_id , CAL_PROPERTY_FLAG_DIRTY))  )
+        {
+            field_name = property_info[i].fields;
+
+            if (field_name == NULL)
+            {
+                continue;
+            }
+
+            if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_INT) == true)
+            {
+                int tmp=0;
+                ret = calendar_record_get_int(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d",field_name,tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_STR) == true)
+            {
+                char *tmp=NULL;
+                ret = calendar_record_get_str(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=?",field_name);
+                *bind_text = g_slist_append(*bind_text, tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_DOUBLE) == true)
+            {
+                double tmp=0;
+                ret = calendar_record_get_double(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%lf",field_name,tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_LLI) == true)
+            {
+                long long int tmp=0;
+                ret = calendar_record_get_lli(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if (strlen(out_set) != 0)
+                {
+                    len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                }
+                len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%lld",field_name,tmp);
+            }
+            else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id,CAL_PROPERTY_DATA_TYPE_CALTIME) == true)
+            {
+                /*
+                 * field_name
+                 * dtstart_type, dtstart_utime, dtstart_datetime
+                 *      -> dtstart_type=%d, dtstart_utime=%lli, dtstart_datetime=?
+                 * dtend_type, dtend_utime, dtend_datetime
+                 *      -> dtend_type=%d, dtend_utime=%lli, dtend_datetime=?
+                 * until_type, until_utime, until_datetime
+                 *      -> until_type=%d, until_utime=%lli, until_datetime=?
+                 */
+                calendar_time_s tmp = {0,};
+                const char *timetype_field = NULL;
+                const char *utime_field = NULL;
+                const char *datetime_field = NULL;
+                timetype_field = __cal_db_query_get_timetype_field_name(field_name);
+                utime_field = __cal_db_query_get_utime_field_name(field_name);
+                datetime_field = __cal_db_query_get_datetime_field_name(field_name);
+                ret = calendar_record_get_caltime(record,property_info[i].property_id,&tmp);
+                if (ret != CALENDAR_ERROR_NONE)
+                    continue;
+                if(tmp.type == CALENDAR_TIME_UTIME)
+                {
+                    if (strlen(out_set) != 0)
+                    {
+                        len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                    }
+                    len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d, %s=%lld",
+                            timetype_field,CALENDAR_TIME_UTIME,utime_field,tmp.time.utime);
+                }
+                else
+                {
+                    char *bind_tmp = NULL;
+                    char bind_datetime[32] = {0};
+                    snprintf(bind_datetime, sizeof(bind_datetime), "%04d%02d%02d",
+                            tmp.time.date.year,
+                            tmp.time.date.month,
+                            tmp.time.date.mday);
+
+                    if (strlen(out_set) != 0)
+                    {
+                        len += snprintf(out_set+len, sizeof(out_set)-len, ", ");
+                    }
+                    len += snprintf(out_set+len, sizeof(out_set)-len, "%s=%d, %s=?",
+                                                       timetype_field, CALENDAR_TIME_LOCALTIME, datetime_field);
+
+                    bind_tmp= strdup(bind_datetime);
+                    *bind_text = g_slist_append(*bind_text, bind_tmp);
+                }
+            }
+        }
+    }
+
+    *set = strdup(out_set);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_query_create_composite_condition(cal_composite_filter_s *com_filter, char **condition, GSList **bind_text)
+{
+    GSList *cursor_filter = NULL;
+    GSList *cursor_ops = NULL;
+    calendar_filter_operator_e op;
+    int len = 0;
+    char *cond = NULL, out_cond[CAL_DB_SQL_MAX_LEN] = {0,};
+    GSList *binds = NULL, *binds2 = NULL;
+    cal_filter_s *filter;
+    int ret = CALENDAR_ERROR_NONE;
+
+       if (com_filter == NULL || com_filter->filters == NULL)
+       {
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+    filter = (cal_filter_s *)com_filter->filters->data;
+    if(filter->filter_type == CAL_FILTER_COMPOSITE)
+    {
+        ret = __cal_db_query_create_composite_condition((cal_composite_filter_s*)filter, &cond, &binds);
+    }
+    else
+    {
+        ret = __cal_db_query_create_attribute_condition(com_filter, (cal_attribute_filter_s*)filter, &cond, &binds);
+    }
+
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("__cal_db_query_create_attribute_condition fail");
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    cursor_filter = com_filter->filters->next;
+
+    len = 0;
+    len = snprintf(out_cond, sizeof(out_cond), "(%s)", cond);
+    CAL_FREE(cond);
+
+    for(cursor_ops=com_filter->filter_ops; cursor_ops && cursor_filter;
+            cursor_filter=cursor_filter->next, cursor_ops=cursor_ops->next)
+    {
+        filter = (cal_filter_s *)cursor_filter->data;
+        if(filter->filter_type == CAL_FILTER_COMPOSITE)
+        {
+            ret = __cal_db_query_create_composite_condition((cal_composite_filter_s*)filter, &cond, &binds2);
+        }
+        else
+        {
+            ret = __cal_db_query_create_attribute_condition(com_filter, (cal_attribute_filter_s*)filter, &cond, &binds2);
+        }
+
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("__cal_db_query_create_attribute_condition fail");
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+
+        op = (calendar_filter_operator_e)cursor_ops->data;
+        if (op == CALENDAR_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(binds2)
+            binds = g_slist_concat(binds, binds2);
+        binds2 = NULL;
+
+        CAL_FREE(cond);
+    }
+
+    *condition = strdup(out_cond);
+    *bind_text = binds;
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_query_create_attribute_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition, GSList **bind_text)
+{
+    int ret;
+    char *cond = NULL;
+
+    retv_if(NULL == filter, CALENDAR_ERROR_INVALID_PARAMETER);
+
+    switch (filter->filter_type)
+    {
+    case CAL_FILTER_INT:
+        ret = __cal_db_query_create_int_condition(com_filter, filter, &cond);
+        break;
+    case CAL_FILTER_STR:
+        ret = __cal_db_query_create_str_condition(com_filter, filter, &cond, bind_text);
+        break;
+    case CAL_FILTER_DOUBLE:
+        ret = __cal_db_query_create_double_condition(com_filter, filter, &cond);
+        break;
+    case CAL_FILTER_LLI:
+        ret = __cal_db_query_create_lli_condition(com_filter, filter, &cond);
+        break;
+    case CAL_FILTER_CALTIME:
+        ret = __cal_db_query_create_caltime_condition(com_filter, filter, &cond);
+        break;
+    default :
+        ERR("The filter type is not supported (%d)", filter->filter_type);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (CALENDAR_ERROR_NONE == ret)
+        *condition = (cond);
+
+    return ret;
+}
+
+static int __cal_db_query_create_int_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition )
+{
+    const char *field_name;
+    char out_cond[CAL_DB_SQL_MAX_LEN] = {0};
+
+    field_name = __cal_db_query_get_property_field_name(com_filter->properties,
+                            com_filter->property_count, filter->property_id);
+    retvm_if(NULL == field_name, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property id(%d)", filter->property_id);
+
+    switch(filter->match)
+    {
+    case CALENDAR_MATCH_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s = %d", field_name, filter->value.i);
+        break;
+    case CALENDAR_MATCH_GREATER_THAN:
+        snprintf(out_cond, sizeof(out_cond), "%s > %d", field_name, filter->value.i);
+        break;
+    case CALENDAR_MATCH_GREATER_THAN_OR_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s >= %d", field_name, filter->value.i);
+        break;
+    case CALENDAR_MATCH_LESS_THAN:
+        snprintf(out_cond, sizeof(out_cond), "%s < %d", field_name, filter->value.i);
+        break;
+    case CALENDAR_MATCH_LESS_THAN_OR_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s <= %d", field_name, filter->value.i);
+        break;
+    case CALENDAR_MATCH_NONE:
+        snprintf(out_cond, sizeof(out_cond), "%s IS NULL", field_name);
+        break;
+    case CALENDAR_MATCH_NOT_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s <> %d", field_name, filter->value.i);
+        break;
+    default :
+        ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    *condition = strdup(out_cond);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_query_create_double_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition )
+{
+    const char *field_name;
+    char out_cond[CAL_DB_SQL_MAX_LEN] = {0};
+
+    field_name = __cal_db_query_get_property_field_name(com_filter->properties,
+                            com_filter->property_count, filter->property_id);
+    retvm_if(NULL == field_name, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property id(%d)", filter->property_id);
+
+    switch(filter->match)
+    {
+    case CALENDAR_MATCH_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s = %lf", field_name, filter->value.d);
+        break;
+    case CALENDAR_MATCH_GREATER_THAN:
+        snprintf(out_cond, sizeof(out_cond), "%s > %lf", field_name, filter->value.d);
+        break;
+    case CALENDAR_MATCH_GREATER_THAN_OR_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s >= %lf", field_name, filter->value.d);
+        break;
+    case CALENDAR_MATCH_LESS_THAN:
+        snprintf(out_cond, sizeof(out_cond), "%s < %lf", field_name, filter->value.d);
+        break;
+    case CALENDAR_MATCH_LESS_THAN_OR_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s <= %lf", field_name, filter->value.d);
+        break;
+    case CALENDAR_MATCH_NONE:
+        snprintf(out_cond, sizeof(out_cond), "%s IS NULL", field_name);
+        break;
+    case CALENDAR_MATCH_NOT_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s <> %lf", field_name, filter->value.d);
+        break;
+    default :
+        ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    *condition = strdup(out_cond);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_query_create_lli_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition )
+{
+    const char *field_name;
+    char out_cond[CAL_DB_SQL_MAX_LEN] = {0};
+
+    field_name = __cal_db_query_get_property_field_name(com_filter->properties,
+                            com_filter->property_count, filter->property_id);
+    retvm_if(NULL == field_name, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property id(%d)", filter->property_id);
+
+    switch(filter->match)
+    {
+    case CALENDAR_MATCH_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s = %lld", field_name, filter->value.lli);
+        break;
+    case CALENDAR_MATCH_GREATER_THAN:
+        snprintf(out_cond, sizeof(out_cond), "%s > %lld", field_name, filter->value.lli);
+        break;
+    case CALENDAR_MATCH_GREATER_THAN_OR_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s >= %lld", field_name, filter->value.lli);
+        break;
+    case CALENDAR_MATCH_LESS_THAN:
+        snprintf(out_cond, sizeof(out_cond), "%s < %lld", field_name, filter->value.lli);
+        break;
+    case CALENDAR_MATCH_LESS_THAN_OR_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s <= %lld", field_name, filter->value.lli);
+        break;
+    case CALENDAR_MATCH_NONE:
+        snprintf(out_cond, sizeof(out_cond), "%s IS NULL", field_name);
+        break;
+    case CALENDAR_MATCH_NOT_EQUAL:
+        snprintf(out_cond, sizeof(out_cond), "%s <> %lld", field_name, filter->value.lli);
+        break;
+    default :
+        ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    *condition = strdup(out_cond);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_query_create_caltime_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition )
+{
+    const char *field_name;
+    char out_cond[CAL_DB_SQL_MAX_LEN] = {0};
+    const char *tmp = NULL;
+
+    field_name = __cal_db_query_get_property_field_name(com_filter->properties,
+                            com_filter->property_count, filter->property_id);
+    retvm_if(NULL == field_name, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property id(%d)", filter->property_id);
+
+    if (filter->value.caltime.type == CALENDAR_TIME_UTIME )
+    {
+        tmp = __cal_db_query_get_utime_field_name(field_name);
+        if (tmp == NULL)
+        {
+            tmp = field_name;
+        }
+        switch(filter->match)
+        {
+        case CALENDAR_MATCH_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s = %lld", tmp, filter->value.caltime.time.utime);
+            break;
+        case CALENDAR_MATCH_GREATER_THAN:
+            snprintf(out_cond, sizeof(out_cond), "%s > %lld", tmp, filter->value.caltime.time.utime);
+            break;
+        case CALENDAR_MATCH_GREATER_THAN_OR_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s >= %lld", tmp, filter->value.caltime.time.utime);
+            break;
+        case CALENDAR_MATCH_LESS_THAN:
+            snprintf(out_cond, sizeof(out_cond), "%s < %lld", tmp, filter->value.caltime.time.utime);
+            break;
+        case CALENDAR_MATCH_LESS_THAN_OR_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s <= %lld", tmp, filter->value.caltime.time.utime);
+            break;
+        case CALENDAR_MATCH_NONE:
+            snprintf(out_cond, sizeof(out_cond), "%s IS NULL", tmp);
+            break;
+        case CALENDAR_MATCH_NOT_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s <> %lld", tmp, filter->value.caltime.time.utime);
+            break;
+        default :
+            ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else if (filter->value.caltime.type == CALENDAR_TIME_LOCALTIME )
+    {
+        char sdate[32] = {0};
+        snprintf(sdate, sizeof(sdate), "%4d%02d%02d", filter->value.caltime.time.date.year
+                , filter->value.caltime.time.date.month, filter->value.caltime.time.date.mday);
+        tmp = __cal_db_query_get_datetime_field_name(field_name);
+        if (tmp == NULL)
+        {
+            tmp = field_name;
+        }
+        switch(filter->match)
+        {
+        case CALENDAR_MATCH_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s = %s", tmp, sdate);
+            break;
+        case CALENDAR_MATCH_GREATER_THAN:
+            snprintf(out_cond, sizeof(out_cond), "%s > %s", tmp, sdate);
+            break;
+        case CALENDAR_MATCH_GREATER_THAN_OR_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s >= %s", tmp, sdate);
+            break;
+        case CALENDAR_MATCH_LESS_THAN:
+            snprintf(out_cond, sizeof(out_cond), "%s < %s", tmp, sdate);
+            break;
+        case CALENDAR_MATCH_LESS_THAN_OR_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s <= %s", tmp, sdate);
+            break;
+        case CALENDAR_MATCH_NOT_EQUAL:
+            snprintf(out_cond, sizeof(out_cond), "%s <> %s", tmp, sdate);
+            break;
+        case CALENDAR_MATCH_NONE:
+        default :
+            ERR("Invalid parameter : int match rule(%d) is not supported", filter->match);
+            return CALENDAR_ERROR_INVALID_PARAMETER;
+        }
+    }
+    else
+    {
+        ERR("Invalid parameter : property id(%d)", filter->property_id);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    *condition = strdup(out_cond);
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_db_query_create_str_condition(cal_composite_filter_s *com_filter,
+        cal_attribute_filter_s *filter, char **condition, GSList **bind_text)
+{
+    const char *field_name;
+    char out_cond[CAL_DB_SQL_MAX_LEN] = {0};
+
+    field_name = __cal_db_query_get_property_field_name(com_filter->properties,
+                            com_filter->property_count, filter->property_id);
+    retvm_if(NULL == field_name, CALENDAR_ERROR_INVALID_PARAMETER,
+            "Invalid parameter : property id(%d)", filter->property_id);
+
+    switch(filter->match)
+    {
+    case CALENDAR_MATCH_EXACTLY:
+        snprintf(out_cond, sizeof(out_cond), "%s = ?", field_name);
+        break;
+    case CALENDAR_MATCH_FULLSTRING:
+        snprintf(out_cond, sizeof(out_cond), "%s LIKE ?", field_name);
+        break;
+    case CALENDAR_MATCH_CONTAINS:
+        snprintf(out_cond, sizeof(out_cond), "%s LIKE '%%' || ? || '%%'", field_name);
+        break;
+    case CALENDAR_MATCH_STARTSWITH:
+        snprintf(out_cond, sizeof(out_cond), "%s LIKE ? || '%%'", field_name);
+        break;
+    case CALENDAR_MATCH_ENDSWITH:
+        snprintf(out_cond, sizeof(out_cond), "%s LIKE '%%' || ?", field_name);
+        break;
+    case CALENDAR_MATCH_EXISTS:
+        snprintf(out_cond, sizeof(out_cond), "%s IS NOT NULL", field_name);
+        break;
+    default :
+        ERR("Invalid paramter : int match rule (%d) is not supported", filter->match);
+        return CALENDAR_ERROR_INVALID_PARAMETER;
+    }
+
+    if (filter->value.s)
+    {
+        *bind_text = g_slist_append(*bind_text, filter->value.s);
+    }
+    *condition = strdup(out_cond);
+    return CALENDAR_ERROR_NONE;
+}
+
+static const char * __cal_db_query_get_property_field_name(const cal_property_info_s *properties,
+        int count, unsigned int property_id)
+{
+    int i;
+    for (i=0;i<count;i++)
+    {
+        cal_property_info_s *p = (cal_property_info_s*)&(properties[i]);
+        if (property_id == p->property_id)
+        {
+            if (p->fields)
+                return p->fields;
+            else
+                return NULL; //ctsvc_get_display_column();
+        }
+    }
+    return NULL;
+}
+
+static const char * __cal_db_query_get_utime_field_name(const char* src)
+{
+    char *tmp1 = NULL;
+    int i=0;
+
+    for(i=0;i<CAL_DB_CALTIME_FIELD_MAX;i++)
+    {
+        tmp1 = strstr(src,__cal_db_utime_field_name[i]);
+        if (tmp1 != NULL)
+        {
+            return __cal_db_utime_field_name[i];
+        }
+    }
+
+    return NULL;
+}
+
+static const char * __cal_db_query_get_datetime_field_name(const char* src)
+{
+    char *tmp1 = NULL;
+    int i=0;
+
+    for(i=0;i<CAL_DB_CALTIME_FIELD_MAX;i++)
+    {
+        tmp1 = strstr(src,__cal_db_datetime_field_name[i]);
+        if (tmp1 != NULL)
+        {
+            return __cal_db_datetime_field_name[i];
+        }
+    }
+
+    return NULL;
+}
+
+static const char * __cal_db_query_get_timetype_field_name(const char* src)
+{
+    char *tmp1 = NULL;
+    int i=0;
+
+    for(i=0;i<CAL_DB_CALTIME_FIELD_MAX;i++)
+    {
+        tmp1 = strstr(src,__cal_db_timetype_field_name[i]);
+        if (tmp1 != NULL)
+        {
+            return __cal_db_timetype_field_name[i];
+        }
+    }
+
+    return NULL;
+}
+
diff --git a/native/cal_db_query.h b/native/cal_db_query.h
new file mode 100644 (file)
index 0000000..90e5234
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_QUERY_H__
+#define __CALENDAR_SVC_DB_QUERY_H__
+
+/*
+ * bind_text->date string is only pointer copy.
+        if (bind_text)
+        {
+            g_slist_free(bind_text);
+        }
+        CAL_FREE(condition);
+        CAL_FREE(projection);
+ */
+int _cal_db_query_create_condition(calendar_query_h query, char **condition, GSList **bind_text);
+int _cal_db_query_create_projection(calendar_query_h query, char **projection);
+int _cal_db_query_create_order(calendar_query_h query, char **order);
+bool _cal_db_query_find_projection_property(calendar_query_h query, unsigned int property);
+
+/*
+ *  bind_text is strdup copy
+ *  please check bind_text free
+    CAL_FREE(set);
+    if(bind_text)
+    {
+        for (cursor=bind_text; cursor;cursor=cursor->next)
+        {
+            CAL_FREE(cursor->data);
+        }
+        g_slist_free(bind_text);
+    }
+ */
+int _cal_db_query_create_projection_update_set(calendar_record_h record, char **set, GSList **bind_text);
+int _cal_db_query_create_projection_update_set_with_property(
+        calendar_record_h record, unsigned int *properties, int properties_count,
+        char **set, GSList **bind_text);
+
+#endif // __CALENDAR_SVC_DB_QUERY_H__
diff --git a/native/cal_db_rrule.c b/native/cal_db_rrule.c
new file mode 100644 (file)
index 0000000..c0286b8
--- /dev/null
@@ -0,0 +1,529 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_view.h"
+#include "cal_time.h"
+
+void _cal_db_rrule_set_default(calendar_record_h event)
+{
+       cal_event_s *_event = NULL;
+       retm_if(event == NULL, "Invalid argument: rrule is NULL");
+
+       _event = (cal_event_s *)event;
+
+       switch (_event->freq)
+       {
+       case CALENDAR_RECURRENCE_NONE:
+               break;
+       case CALENDAR_RECURRENCE_DAILY:
+               break;
+       case CALENDAR_RECURRENCE_WEEKLY:
+               if (_event->bymonthday || _event->byday)
+                       break;
+
+               _event->byday = _cal_time_extract_by(_event->start_tzid,
+                               _event->wkst, &_event->start, CAL_DAY_OF_WEEK);
+               DBG("No byday so set default[%s]", _event->byday);
+               break;
+
+       case CALENDAR_RECURRENCE_MONTHLY:
+               if (_event->bymonthday || _event->byday)
+                       break;
+
+               _event->bymonthday = _cal_time_extract_by(_event->start_tzid,
+                               _event->wkst, &_event->start, CAL_DATE);
+               DBG("No bymonthday so set default[%s]", _event->bymonthday);
+               break;
+
+       case CALENDAR_RECURRENCE_YEARLY:
+               break;
+       default:
+               break;
+       }
+}
+
+void _cal_db_rrule_get_rrule_from_event(calendar_record_h event, cal_rrule_s **rrule)
+{
+       cal_rrule_s *_rrule;
+       cal_event_s *_event;
+
+       retm_if(event == NULL, "Invalid argument: rrule is NULL");
+
+       _event = (cal_event_s *)event;
+
+       _rrule = calloc(1, sizeof(cal_rrule_s));
+       retm_if(_rrule == NULL, "Failed to calloc");
+
+       _rrule->freq = _event->freq;
+
+       _rrule->range_type = _event->range_type;
+       switch (_rrule->range_type)
+       {
+       case CALENDAR_RANGE_UNTIL:
+               _rrule->until_type = _event->until_type;
+               switch (_rrule->until_type)
+               {
+               case CALENDAR_TIME_UTIME:
+                       _rrule->until_utime = _event->until_utime;
+                       break;
+
+               case CALENDAR_TIME_LOCALTIME:
+                       _rrule->until_year = _event->until_year;
+                       _rrule->until_month = _event->until_month;
+                       _rrule->until_mday = _event->until_mday;
+                       break;
+               }
+               break;
+
+       case CALENDAR_RANGE_COUNT:
+               break;
+       case CALENDAR_RANGE_NONE:
+               break;
+       }
+
+       _rrule->count = _event->count;
+       _rrule->interval = _event->interval;
+       _rrule->bysecond = _event->bysecond;
+       _rrule->byminute = _event->byminute;
+       _rrule->byhour = _event->byhour;
+       _rrule->byday = _event->byday;
+       _rrule->bymonthday = _event->bymonthday;
+       _rrule->byyearday = _event->byyearday;
+       _rrule->byweekno = _event->byweekno;
+       _rrule->bymonth = _event->bymonth;
+       _rrule->bysetpos = _event->bysetpos;
+       _rrule->wkst = _event->wkst;
+
+       *rrule = _rrule;
+}
+
+void _cal_db_rrule_set_rrule_to_event(cal_rrule_s *rrule, calendar_record_h event)
+{
+       cal_event_s *_event;
+
+       retm_if(rrule == NULL, "Invalid argument: rrule is NULL");
+       retm_if(event == NULL, "Invalid argument: rrule is NULL");
+
+       _event = (cal_event_s *)event;
+
+       _event->freq = rrule->freq;
+       _event->range_type = rrule->range_type;
+       _event->until_type = rrule->until_type;
+       _event->until_utime = rrule->until_utime;
+       _event->until_year = rrule->until_year;
+       _event->until_month = rrule->until_month;
+       _event->until_mday = rrule->until_mday;
+       _event->count = rrule->count;
+       _event->interval = rrule->interval;
+       _event->bysecond = rrule->bysecond;
+       _event->byminute = rrule->byminute;
+       _event->byhour = rrule->byhour;
+       _event->byday = rrule->byday;
+       _event->bymonthday = rrule->bymonthday;
+       _event->byyearday = rrule->byyearday;
+       _event->byweekno = rrule->byweekno;
+       _event->bymonth = rrule->bymonth;
+       _event->bysetpos = rrule->bysetpos;
+       _event->wkst = rrule->wkst;
+}
+
+void _cal_db_rrule_set_rrule_to_todo(cal_rrule_s *rrule, calendar_record_h todo)
+{
+       cal_todo_s *_todo;
+
+       retm_if(rrule == NULL, "Invalid argument: rrule is NULL");
+       retm_if(todo == NULL, "Invalid argument: todo is NULL");
+
+       _todo = (cal_todo_s *)todo;
+
+       _todo->freq = rrule->freq;
+       _todo->range_type = rrule->range_type;
+       _todo->until_type = rrule->until_type;
+       _todo->until_utime = rrule->until_utime;
+       _todo->until_year = rrule->until_year;
+       _todo->until_month = rrule->until_month;
+       _todo->until_mday = rrule->until_mday;
+       _todo->count = rrule->count;
+       _todo->interval = rrule->interval;
+       _todo->bysecond = rrule->bysecond;
+       _todo->byminute = rrule->byminute;
+       _todo->byhour = rrule->byhour;
+       _todo->byday = rrule->byday;
+       _todo->bymonthday = rrule->bymonthday;
+       _todo->byyearday = rrule->byyearday;
+       _todo->byweekno = rrule->byweekno;
+       _todo->bymonth = rrule->bymonth;
+       _todo->bysetpos = rrule->bysetpos;
+       _todo->wkst = rrule->wkst;
+}
+
+void _cal_db_rrule_get_rrule_from_todo(calendar_record_h todo, cal_rrule_s **rrule)
+{
+       cal_rrule_s *_rrule;
+       cal_todo_s *_todo;
+
+       retm_if(todo == NULL, "Invalid argument: rrule is NULL");
+
+       _todo = (cal_todo_s *)todo;
+
+       _rrule = calloc(1, sizeof(cal_rrule_s));
+       retm_if(_rrule == NULL, "Failed to calloc");
+
+       _rrule->freq = _todo->freq;
+       _rrule->range_type = _todo->range_type;
+       _rrule->until_type = _todo->until_type;
+       _rrule->until_utime = _todo->until_utime;
+       _rrule->until_year = _todo->until_year;
+       _rrule->until_month = _todo->until_month;
+       _rrule->until_mday = _todo->until_mday;
+       _rrule->count = _todo->count;
+       _rrule->interval = _todo->interval;
+       _rrule->bysecond = _todo->bysecond;
+       _rrule->byminute = _todo->byminute;
+       _rrule->byhour = _todo->byhour;
+       _rrule->byday = _todo->byday;
+       _rrule->bymonthday = _todo->bymonthday;
+       _rrule->byyearday = _todo->byyearday;
+       _rrule->byweekno = _todo->byweekno;
+       _rrule->bymonth = _todo->bymonth;
+       _rrule->bysetpos = _todo->bysetpos;
+       _rrule->wkst = _todo->wkst;
+
+       *rrule = _rrule;
+}
+
+int _cal_db_rrule_insert_record(int id, cal_rrule_s *rrule)
+{
+       int rrule_id;
+       int index;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char until_datetime[32] = {0};
+       sqlite3_stmt *stmt = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       retvm_if(rrule == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: rrule is NULL");
+
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s ( "
+                       "event_id, freq, range_type, "
+                       "until_type, until_utime, until_datetime, "
+                       "count, interval, "
+                       "bysecond, byminute, byhour, byday, "
+                       "bymonthday, byyearday, byweekno, bymonth, "
+                       "bysetpos, wkst "
+                       ") VALUES ( "
+                       "%d, %d, %d, "
+                       "%d, %lld, ?, "
+                       "%d, %d, "
+                       "?, ?, ?, ?, "
+                       "?, ?, ?, ?, "
+                       "?, %d "
+                       ") ",
+                       CAL_TABLE_RRULE,
+                       id, rrule->freq, rrule->range_type,
+                       rrule->until_type, rrule->until_type == CALENDAR_TIME_UTIME ? rrule->until_utime : 0,
+                       rrule->count, rrule->interval,
+                       rrule->wkst);
+
+       DBG("[%s]", query);
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(stmt == NULL, CALENDAR_ERROR_DB_FAILED, "Failed to query prepare");
+
+       index = 1;
+
+       if (CALENDAR_TIME_LOCALTIME == rrule->until_type)
+       {
+               snprintf(until_datetime, sizeof(until_datetime), "%04d%02d%02d",
+                               rrule->until_year, rrule->until_month, rrule->until_mday);
+               _cal_db_util_stmt_bind_text(stmt, index, until_datetime);
+       }
+       index++;
+
+       if (rrule->bysecond)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bysecond);
+       index++;
+
+       if (rrule->byminute)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byminute);
+       index++;
+
+       if (rrule->byhour)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byhour);
+       index++;
+
+       if (rrule->byday)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byday);
+       index++;
+
+       if (rrule->bymonthday)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bymonthday);
+       index++;
+
+       if (rrule->byyearday)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byyearday);
+       index++;
+
+       if (rrule->byweekno)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byweekno);
+       index++;
+
+       if (rrule->bymonth)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bymonth);
+       index++;
+
+       if (rrule->bysetpos)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bysetpos);
+       index++;
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+       if (CAL_DB_OK != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       rrule_id = _cal_db_util_last_insert_id();
+       DBG("rrule_id(%d)", rrule_id);
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_rrule_get_rrule(int id, cal_rrule_s **rrule)
+{
+       char query[CAL_DB_SQL_MAX_LEN];
+       int index;
+       sqlite3_stmt *stmt = NULL;
+       cal_rrule_s *_rrule = NULL;
+       const unsigned char *temp;
+       cal_db_util_error_e dbret = CAL_DB_OK;
+
+       _rrule = calloc(1, sizeof(cal_rrule_s));
+       retvm_if(_rrule == NULL, CALENDAR_ERROR_OUT_OF_MEMORY,
+                       "Failed to calloc");
+
+       snprintf(query, sizeof(query),
+                       "SELECT * FROM %s "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_RRULE,
+                       id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() Failed");
+               CAL_FREE(_rrule);
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (dbret != CAL_DB_ROW) {
+               ERR("Failed to step stmt(%d)", dbret);
+               sqlite3_finalize(stmt);
+               CAL_FREE(_rrule);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       index = 0;
+       sqlite3_column_int(stmt, index++); // id
+       sqlite3_column_int(stmt, index++); // event_id
+       _rrule->freq = sqlite3_column_int(stmt, index++);
+
+       //rrule->_rrule_id = 1;
+       _rrule->range_type = sqlite3_column_int(stmt, index++);
+       _rrule->until_type = sqlite3_column_int(stmt, index++);
+       _rrule->until_utime = sqlite3_column_int64(stmt, index++);
+
+       temp = sqlite3_column_text(stmt, index++);
+       if (CALENDAR_TIME_LOCALTIME == _rrule->until_type)
+       {
+               sscanf((const char *)temp, "%04d%02d%02d",
+                               &_rrule->until_year, &_rrule->until_month, &_rrule->until_mday);
+       }
+
+       _rrule->count = sqlite3_column_int(stmt, index++);
+       _rrule->interval = sqlite3_column_int(stmt, index++);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->bysecond = SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->byminute = SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->byhour = SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->byday= SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->bymonthday= SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->byyearday= SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->byweekno= SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->bymonth= SAFE_STRDUP(temp);
+
+       temp = sqlite3_column_text(stmt, index++);
+       _rrule->bysetpos = SAFE_STRDUP(temp);
+
+       _rrule->wkst = sqlite3_column_int(stmt, index++);
+
+       sqlite3_finalize(stmt);
+
+       *rrule = _rrule;
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_rrule_update_record(int id, cal_rrule_s *rrule)
+{
+       int dbret;
+       int index;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+       char until_datetime[32] = {0};
+       sqlite3_stmt *stmt = NULL;
+
+       retvm_if(rrule == NULL, CALENDAR_ERROR_INVALID_PARAMETER,
+                       "Invalid argument: rrule is NULL");
+
+       if (rrule->freq == CALENDAR_RECURRENCE_NONE)
+       {
+               DBG("freq is NONE");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       DBG("freq exist, so update rrule");
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET "
+                       "freq = %d, "
+                       "range_type = %d, "
+                       "until_type = %d, "
+                       "until_utime = %lld, "
+                       "until_datetime = ?, "
+                       "count = %d, "
+                       "interval = %d, "
+                       "bysecond = ?, "
+                       "byminute= ?, "
+                       "byhour = ?, "
+                       "byday = ?, "
+                       "bymonthday = ?, "
+                       "byyearday = ?, "
+                       "byweekno = ?, "
+                       "bymonth = ?, "
+                       "bysetpos = ?, "
+                       "wkst = %d "
+                       "WHERE event_id = %d ",
+                       CAL_TABLE_RRULE,
+                       rrule->freq,
+                       rrule->range_type,
+                       rrule->until_type,
+                       rrule->until_type == CALENDAR_TIME_UTIME ? rrule->until_utime : 0,
+                       rrule->count,
+                       rrule->interval,
+                       rrule->wkst,
+                       id);
+
+       DBG("query[%s]", query);
+       stmt = _cal_db_util_query_prepare(query);
+       retvm_if(stmt == NULL, CALENDAR_ERROR_DB_FAILED,
+                       "_cal_db_util_query_prepare() Failed");
+
+       index = 1;
+
+       if (CALENDAR_TIME_LOCALTIME == rrule->until_type)
+       {
+               snprintf(until_datetime, sizeof(until_datetime), "%04d%02d%02d",
+                               rrule->until_year, rrule->until_month, rrule->until_mday);
+               _cal_db_util_stmt_bind_text(stmt, index, until_datetime);
+       }
+       index++;
+
+       if (rrule->bysecond)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bysecond);
+       index++;
+
+       if (rrule->byminute)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byminute);
+       index++;
+
+       if (rrule->byhour)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byhour);
+       index++;
+
+       if (rrule->byday)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byday);
+       index++;
+
+       if (rrule->bymonthday)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bymonthday);
+       index++;
+
+       if (rrule->byyearday)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byyearday);
+       index++;
+
+       if (rrule->byweekno)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->byweekno);
+       index++;
+
+       if (rrule->bymonth)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bymonth);
+       index++;
+
+       if (rrule->bysetpos)
+               _cal_db_util_stmt_bind_text(stmt, index, rrule->bysetpos);
+       index++;
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+       if (CAL_DB_DONE != dbret) {
+               ERR("sqlite3_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
diff --git a/native/cal_db_rrule.h b/native/cal_db_rrule.h
new file mode 100644 (file)
index 0000000..a52c9ed
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_RRULE_H__
+#define __CALENDAR_SVC_DB_RRULE_H__
+
+void _cal_db_rrule_set_default(calendar_record_h event);
+int _cal_db_rrule_insert_record(int id, cal_rrule_s *rrule);
+int _cal_db_rrule_update_record(int id, cal_rrule_s *rrule);
+int _cal_db_rrule_get_rrule(int id, cal_rrule_s **rrule);
+void _cal_db_rrule_get_rrule_from_event(calendar_record_h event, cal_rrule_s **rrule);
+void _cal_db_rrule_set_rrule_to_event(cal_rrule_s *rrule, calendar_record_h event);
+void _cal_db_rrule_get_rrule_from_todo(calendar_record_h todo, cal_rrule_s **rrule);
+void _cal_db_rrule_set_rrule_to_todo(cal_rrule_s *rrule, calendar_record_h todo);
+
+#endif  //__CALENDAR_SVC_DB_RRULE_H__
diff --git a/native/cal_db_util.c b/native/cal_db_util.c
new file mode 100644 (file)
index 0000000..1c3b7b5
--- /dev/null
@@ -0,0 +1,370 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <stdbool.h>
+#include <db-util.h>
+
+#include "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_db.h"
+
+#include "cal_db_util.h"
+
+static TLS sqlite3 *calendar_db_handle;
+static TLS int transaction_cnt = 0;
+static TLS int transaction_ver = 0;
+static TLS bool version_up = false;
+
+static TLS bool event_change=false;
+static TLS bool todo_change=false;
+static TLS bool calendar_change=false;
+
+static inline void __cal_db_util_notify_event_change(void)
+{
+       int fd = open(CAL_NOTI_EVENT_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               event_change = false;
+       }
+}
+
+static inline void __cal_db_util_notify_todo_change(void)
+{
+       int fd = open(CAL_NOTI_TODO_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               todo_change = false;
+       }
+}
+
+static inline void __cal_db_util_notify_calendar_change(void)
+{
+       int fd = open(CAL_NOTI_CALENDAR_CHANGED, O_TRUNC | O_RDWR);
+       if (0 <= fd) {
+               close(fd);
+               calendar_change = false;
+       }
+}
+
+static inline void __cal_db_util_cancel_changes(void)
+{
+    event_change = false;
+    calendar_change = false;
+    todo_change = false;
+}
+
+int _cal_db_util_notify(cal_noti_type_e type)
+{
+       if (0 < transaction_cnt) {
+               switch (type) {
+               case CAL_NOTI_TYPE_EVENT:
+                       event_change = true;
+                       break;
+               case CAL_NOTI_TYPE_TODO:
+                       todo_change = true;
+                       break;
+               case CAL_NOTI_TYPE_CALENDAR:
+                       calendar_change = true;
+                       break;
+               default:
+                       ERR("The type(%d) is not supported", type);
+                       return CALENDAR_ERROR_INVALID_PARAMETER;
+               }
+               return CALENDAR_ERROR_NONE;
+       }
+
+       switch(type) {
+       case CAL_NOTI_TYPE_EVENT:
+               __cal_db_util_notify_event_change();
+               break;
+       case CAL_NOTI_TYPE_TODO:
+               __cal_db_util_notify_todo_change();
+               break;
+       case CAL_NOTI_TYPE_CALENDAR:
+               __cal_db_util_notify_calendar_change();
+               break;
+       default:
+               ERR("The type(%d) is not supported", type);
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_util_open(void)
+{
+       int ret = 0;
+
+       if (!calendar_db_handle) {
+               ret = db_util_open(CAL_DB_PATH, &calendar_db_handle, 0);
+               retvm_if(SQLITE_OK != ret, CALENDAR_ERROR_DB_FAILED,
+                               "db_util_open() Failed(%d).", ret);
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_util_close(void)
+{
+       int ret = 0;
+
+       if (calendar_db_handle) {
+               ret = db_util_close(calendar_db_handle);
+               warn_if(SQLITE_OK != ret, "db_util_close() Failed(%d)", ret);
+               calendar_db_handle = NULL;
+               CAL_DBG("The database disconnected really.");
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_util_last_insert_id(void)
+{
+       return sqlite3_last_insert_rowid(calendar_db_handle);
+}
+
+int _cal_db_util_query_get_first_int_result(const char *query, GSList *bind_text, int *result)
+{
+       int ret;
+       int index;
+       char *text = NULL;
+       sqlite3_stmt *stmt = NULL;
+       retvm_if(NULL == calendar_db_handle, CALENDAR_ERROR_DB_FAILED, "Database is not opended");
+
+       ret = sqlite3_prepare_v2(calendar_db_handle, query, strlen(query), &stmt, NULL);
+       retvm_if(SQLITE_OK != ret, CALENDAR_ERROR_DB_FAILED,
+                       "sqlite3_prepare_v2(%s) failed(%s).", query, sqlite3_errmsg(calendar_db_handle));
+
+       if (bind_text)
+       {
+               for (index = 0; g_slist_nth(bind_text, index); index++)
+               {
+                       text = (char *)g_slist_nth_data(bind_text, index);
+                       if (text)
+                       {
+                               _cal_db_util_stmt_bind_text(stmt, index + 1, text);
+                       }
+               }
+       }
+
+       ret = sqlite3_step(stmt);
+       if (SQLITE_ROW != ret)
+       {
+               ERR("sqlite3_step() failed(%d, %s).", ret, sqlite3_errmsg(calendar_db_handle));
+               sqlite3_finalize(stmt);
+               if (SQLITE_DONE == ret) return CALENDAR_ERROR_DB_FAILED;
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       if (result) *result = sqlite3_column_int(stmt, 0);
+       sqlite3_finalize(stmt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+cal_db_util_error_e _cal_db_util_query_exec(char *query)
+{
+       int ret;
+       char *err_msg = NULL;
+
+       retvm_if(NULL == calendar_db_handle, CALENDAR_ERROR_DB_FAILED, "Database is not opended");
+       //CALS_DBG("query : %s", query);
+
+       ret = sqlite3_exec(calendar_db_handle, query, NULL, NULL, &err_msg);
+       if (SQLITE_OK != ret) {
+               ERR("sqlite3_exec(%s) failed(%d, %s).", query, ret, err_msg);
+               sqlite3_free(err_msg);
+               switch (ret) {
+               case SQLITE_BUSY:
+               case SQLITE_LOCKED:
+                       return CAL_DB_ERROR_LOCKED;
+               case SQLITE_IOERR:
+                       return CAL_DB_ERROR_IOERR;
+               case SQLITE_FULL:
+                       return CAL_DB_ERROR_NO_SPACE;
+               default:
+                       return CAL_DB_ERROR_FAIL;
+               }
+       }
+       if (err_msg)
+       {
+           sqlite3_free(err_msg);
+       }
+
+       return CAL_DB_OK;
+}
+
+sqlite3_stmt* _cal_db_util_query_prepare(char *query)
+{
+       int ret = -1;
+       sqlite3_stmt *stmt = NULL;
+
+       retvm_if(NULL == query, NULL, "Invalid query");
+       retvm_if(NULL == calendar_db_handle, NULL, "Database is not opended");
+       //CALS_DBG("prepare query : %s", query);
+
+       ret = sqlite3_prepare_v2(calendar_db_handle, query, strlen(query), &stmt, NULL);
+       retvm_if(SQLITE_OK != ret, NULL,
+                       "sqlite3_prepare_v2(%s) Failed(%s).", query, sqlite3_errmsg(calendar_db_handle));
+
+       return stmt;
+}
+
+cal_db_util_error_e _cal_db_util_stmt_step(sqlite3_stmt *stmt)
+{
+       int ret;
+       ret = sqlite3_step(stmt);
+    switch (ret) {
+    case SQLITE_BUSY:
+    case SQLITE_LOCKED:
+        ret = CAL_DB_ERROR_LOCKED;
+        break;
+    case SQLITE_IOERR:
+        ret = CAL_DB_ERROR_IOERR;
+        break;
+    case SQLITE_FULL:
+        ret = CAL_DB_ERROR_NO_SPACE;
+        break;
+    case SQLITE_CONSTRAINT:
+        ret = CAL_DB_ERROR_ALREADY_EXIST;
+        break;
+    case SQLITE_ROW:
+        ret = CAL_DB_ROW;
+        break;
+    case SQLITE_DONE:
+        ret = CAL_DB_DONE;
+        break;
+    default:
+        ERR("sqlite3_step() Failed(%d)", ret);
+        ret = CAL_DB_ERROR_FAIL;
+        break;
+    }
+    return ret;
+}
+
+#define CAL_COMMIT_TRY_MAX 500000
+int _cal_db_util_begin_trans(void)
+{
+       if(transaction_cnt <= 0)
+       {
+               int ret, progress;
+
+               progress = 100000;
+               ret = _cal_db_util_query_exec("BEGIN IMMEDIATE TRANSACTION");
+               // !! check error code
+               while(CAL_DB_OK != ret && progress < CAL_COMMIT_TRY_MAX) {
+                       usleep(progress);
+                       ret = _cal_db_util_query_exec("BEGIN IMMEDIATE TRANSACTION");
+                       progress *= 2;
+               }
+               retvm_if(CAL_DB_OK != ret, ret, "cal_query_exec() Failed(%d)", ret);
+
+               transaction_cnt = 0;
+               const char *query = "SELECT ver FROM "CAL_TABLE_VERSION;
+               ret = _cal_db_util_query_get_first_int_result(query, NULL, &transaction_ver);
+               if (CALENDAR_ERROR_NONE != ret)
+               {
+                       ERR("_cal_db_util_query_get_first_int_result() failed");
+                       return ret;
+               }
+               version_up = false;
+       }
+       transaction_cnt++;
+       CAL_DBG("transaction_cnt : %d", transaction_cnt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_util_end_trans(bool is_success)
+{
+       int ret;
+       int progress = 0;
+       char query[CAL_DB_SQL_MIN_LEN];
+
+       transaction_cnt--;
+
+       if (0 != transaction_cnt) {
+               CAL_DBG("transaction_cnt : %d", transaction_cnt);
+               return CALENDAR_ERROR_NONE;
+       }
+
+       if (false == is_success) {
+               __cal_db_util_cancel_changes();
+               ret = _cal_db_util_query_exec("ROLLBACK TRANSACTION");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       if (version_up) {
+               transaction_ver++;
+               snprintf(query, sizeof(query), "UPDATE %s SET ver = %d",
+                               CAL_TABLE_VERSION, transaction_ver);
+               ret = _cal_db_util_query_exec(query);
+               warn_if(CAL_DB_OK != ret, "cal_query_exec(version up) Failed(%d).", ret);
+       }
+
+       progress = 100000;
+       ret = _cal_db_util_query_exec("COMMIT TRANSACTION");
+       // !! check error code
+       while (CAL_DB_OK != ret && progress < CAL_COMMIT_TRY_MAX) {
+               usleep(progress);
+               ret = _cal_db_util_query_exec("COMMIT TRANSACTION");
+               progress *= 2;
+       }
+       if (CAL_DB_OK != ret) {
+               int tmp_ret;
+               ERR("cal_query_exec() Failed(%d)", ret);
+               __cal_db_util_cancel_changes();
+               tmp_ret = _cal_db_util_query_exec("ROLLBACK TRANSACTION");
+               warn_if(CAL_DB_OK != tmp_ret, "cal_query_exec(ROLLBACK) Failed(%d).", tmp_ret);
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       if (event_change) __cal_db_util_notify_event_change();
+       if (todo_change) __cal_db_util_notify_todo_change();
+       if (calendar_change) __cal_db_util_notify_calendar_change();
+
+       CAL_DBG("transaction_ver = %d",transaction_ver);
+       return CALENDAR_ERROR_NONE;
+}
+
+int _cal_db_util_get_next_ver(void)
+{
+       int count = 0;
+       int ret;
+       const char *query;
+
+       if (0 < transaction_cnt) {
+               version_up = true;
+               return transaction_ver + 1;
+       }
+
+       query = "SELECT ver FROM "CAL_TABLE_VERSION;
+
+       ret = _cal_db_util_query_get_first_int_result(query, NULL, &count);
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_db_util_query_get_first_int_result() failed");
+               return ret;
+       }
+       return (1 + count);
+}
+
+int _cal_db_util_get_transaction_ver(void)
+{
+    return transaction_ver;
+}
diff --git a/native/cal_db_util.h b/native/cal_db_util.h
new file mode 100644 (file)
index 0000000..888e184
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CALENDAR_SVC_DB_UTIL_H__
+#define __CALENDAR_SVC_DB_UTIL_H__
+
+#include <sqlite3.h>
+#include <string.h>
+
+typedef enum
+{
+    CAL_DB_ERROR_FAIL   = -1,
+    CAL_DB_ERROR_LOCKED = -204,         //SQLITE_BUSY, SQLITE_LOCKED
+    CAL_DB_ERROR_IOERR = -10,           //SQLITE_IOERR              /* Some kind of disk I/O error occurred */
+    CAL_DB_ERROR_NO_SPACE = -11,        //SQLITE_FULL               /* Insertion failed because database is full */
+    CAL_DB_ERROR_ALREADY_EXIST = -7,    //SQLITE_CONSTRAINT         /* Abort due to constraint violation */
+    CAL_DB_ROW = 1,                     //SQLITE_ROW    CAL_TRUE    /* sqlite3_step() has another row ready */
+    CAL_DB_DONE = 0,                    //SQLITE_DONE   CAL_SUCCESS /* sqlite3_step() has finished executing */
+    CAL_DB_OK = 0,                      //SQLITE_OK                 /* Successful result */
+} cal_db_util_error_e;
+
+int _cal_db_util_notify(cal_noti_type_e type);
+
+int _cal_db_util_open(void);
+int _cal_db_util_close(void);
+
+int _cal_db_util_last_insert_id(void);
+int _cal_db_util_query_get_first_int_result(const char *query, GSList *bind_text, int *result);
+
+cal_db_util_error_e _cal_db_util_query_exec(char *query);
+sqlite3_stmt* _cal_db_util_query_prepare(char *query);
+cal_db_util_error_e _cal_db_util_stmt_step(sqlite3_stmt *stmt);
+
+static inline int _cal_db_util_stmt_bind_text(sqlite3_stmt *stmt, int pos, const char *str) {
+    return sqlite3_bind_text(stmt, pos, str, str ? strlen(str) : 0, SQLITE_STATIC);
+}
+
+int _cal_db_util_begin_trans(void);
+int _cal_db_util_end_trans(bool is_success);
+
+int _cal_db_util_get_next_ver(void);
+
+int _cal_db_util_get_transaction_ver(void);
+
+#endif  //__CALENDAR_SVC_DB_UTIL_H__
diff --git a/native/cal_reminder.c b/native/cal_reminder.c
new file mode 100644 (file)
index 0000000..750b525
--- /dev/null
@@ -0,0 +1,251 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "cal_internal.h"
+#include "cal_typedef.h"
+#include "cal_view.h"
+#include "cal_time.h"
+#include "cal_record.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+
+API int calendar_reminder_add_receiver(const char *pkgname, const char *extra_data_key, const char *extra_data_value)
+{
+       int index;
+       int count = 0;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+
+       if (pkgname == NULL || strlen(pkgname) == 0)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       // check whether already registered
+       snprintf(query, sizeof(query), "SELECT count(*) FROM %s WHERE pkgname = ? ",
+                       CAL_REMINDER_ALERT);
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       _cal_db_util_stmt_bind_text(stmt, 1, pkgname);
+
+       dbret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_ROW == dbret)
+       {
+               index = 0;
+               count = sqlite3_column_int(stmt, index++);
+       }
+       sqlite3_finalize(stmt);
+
+       if (count > 0)
+       {
+               DBG("Already registered pkgname[%s]", pkgname);
+               return CALENDAR_ERROR_NONE;
+       }
+
+       // register
+       snprintf(query, sizeof(query),
+                       "INSERT INTO %s ( pkgname, key, value ) VALUES ( ?, ?, ? ) ",
+                       CAL_REMINDER_ALERT);
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       index = 1;
+       _cal_db_util_stmt_bind_text(stmt, index++, pkgname);
+       _cal_db_util_stmt_bind_text(stmt, index++, extra_data_key);
+       _cal_db_util_stmt_bind_text(stmt, index++, extra_data_value);
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_reminder_remove_receiver(const char *pkgname)
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+
+       if (pkgname == NULL || strlen(pkgname) == 0)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(query, sizeof(query), "DELETE FROM %s WHERE pkgname = ? ",
+                       CAL_REMINDER_ALERT);
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       _cal_db_util_stmt_bind_text(stmt, 1, pkgname);
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_reminder_activate_receiver(const char *pkgname)
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+
+       if (pkgname == NULL || strlen(pkgname) == 0)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET onoff = 1 WHERE pkgname = ? ",
+                       CAL_REMINDER_ALERT);
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       _cal_db_util_stmt_bind_text(stmt, 1, pkgname);
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+
+       if (CAL_DB_DONE != dbret)
+{
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_reminder_deactivate_receiver(const char *pkgname)
+{
+    cal_db_util_error_e dbret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+
+       if (pkgname == NULL || strlen(pkgname) == 0)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(query, sizeof(query), "UPDATE %s SET onoff = 0 WHERE pkgname = ? ",
+                       CAL_REMINDER_ALERT);
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       _cal_db_util_stmt_bind_text(stmt, 1, pkgname);
+       dbret = _cal_db_util_stmt_step(stmt);
+       sqlite3_finalize(stmt);
+
+       if (CAL_DB_DONE != dbret)
+       {
+               ERR("_cal_db_util_stmt_step() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+API int calendar_reminder_has_receiver(const char *pkgname)
+{
+       int index;
+       int count = 0;
+    cal_db_util_error_e ret = CAL_DB_OK;
+       char query[CAL_DB_SQL_MAX_LEN];
+       sqlite3_stmt *stmt;
+
+       if (pkgname == NULL || strlen(pkgname) == 0)
+       {
+               ERR("Invalid parameter");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       snprintf(query, sizeof(query), "SELECT count(*) FROM %s WHERE pkgname = ? ",
+                       CAL_REMINDER_ALERT);
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+       _cal_db_util_stmt_bind_text(stmt, 1, pkgname);
+
+       ret = _cal_db_util_stmt_step(stmt);
+       if (CAL_DB_ROW == ret) {
+               index = 0;
+               count = sqlite3_column_int(stmt, index++);
+       }
+       sqlite3_finalize(stmt);
+
+       return count > 0 ? true : false;
+}
diff --git a/native/calendar-service-native.pc b/native/calendar-service-native.pc
new file mode 100755 (executable)
index 0000000..5051b2f
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/calendar-service-native
+
+Name: calendar-service-native
+Description: calendar-service-native library
+Version: 0.1.13
+Requires: glib-2.0 alarm-service db-util capi-base-common
+Libs: -L${libdir} -lcalendar-service-native
+Cflags: -I${includedir}
diff --git a/native/calendar-service2.pc b/native/calendar-service2.pc
new file mode 100755 (executable)
index 0000000..5051b2f
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=/usr
+exec_prefix=${prefix}
+libdir=${prefix}/lib
+includedir=${prefix}/include/calendar-service-native
+
+Name: calendar-service-native
+Description: calendar-service-native library
+Version: 0.1.13
+Requires: glib-2.0 alarm-service db-util capi-base-common
+Libs: -L${libdir} -lcalendar-service-native
+Cflags: -I${includedir}
diff --git a/packaging/calendar-service.spec b/packaging/calendar-service.spec
new file mode 100644 (file)
index 0000000..edfd4b1
--- /dev/null
@@ -0,0 +1,116 @@
+Name:       calendar-service
+Summary:    DB library for calendar
+Version:    0.1.14
+Release:    46
+Group:      System/Libraries
+License:    Apache 2.0
+Source0:    %{name}-%{version}.tar.gz
+Source1:    calendar.service
+Requires(post): /sbin/ldconfig
+Requires(post): /usr/bin/sqlite3, /bin/chown
+Requires(postun): /sbin/ldconfig
+
+BuildRequires: cmake
+BuildRequires: pkgconfig(db-util)
+BuildRequires: pkgconfig(sqlite3)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: pkgconfig(alarm-service)
+BuildRequires: pkgconfig(icu-i18n)
+BuildRequires: pkgconfig(appsvc)
+BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(contacts-service2)
+BuildRequires: pkgconfig(pims-ipc)
+
+%description
+DB library for calendar
+
+%package devel
+Summary:    DB library for calendar
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+Requires:   pkgconfig(alarm-service)
+
+%description devel
+DB library for calendar (developement files)
+
+%prep
+%setup -q
+
+
+%build
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix}
+
+
+make %{?jobs:-j%jobs}
+
+%install
+%make_install
+
+mkdir -p %{buildroot}/etc/rc.d/rc3.d/
+mkdir -p %{buildroot}/etc/rc.d/rc5.d/
+ln -s ../init.d/calendar-serviced.sh %{buildroot}/etc/rc.d/rc3.d/S85calendar-serviced
+ln -s ../init.d/calendar-serviced.sh %{buildroot}/etc/rc.d/rc5.d/S85calendar-serviced
+
+mkdir -p %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants
+install %{SOURCE1} %{buildroot}%{_libdir}/systemd/user/
+ln -s ../calendar.service %{buildroot}%{_libdir}/systemd/user/tizen-middleware.target.wants/
+
+%post
+/sbin/ldconfig
+
+chown :6003 /opt/usr/data/calendar-svc
+
+mkdir -p /opt/usr/dbspace
+if [ -f /opt/usr/dbspace/.calendar-svc.db ]
+then
+        echo "calendar-svc.db exist"
+else
+               calendar-svc-initdb
+fi
+
+if [ -f /usr/lib/rpm-plugins/msm.so ]
+then
+       chsmack -a 'calendar-service::db' /opt/usr/dbspace/.calendar-svc.db*
+fi
+
+chown :6003 /opt/usr/dbspace/.calendar-svc.db
+chown :6003 /opt/usr/dbspace/.calendar-svc.db-journal
+chown :6003 /opt/usr/data/calendar-svc/.CALENDAR_SVC_*
+
+chmod 660 /opt/usr/dbspace/.calendar-svc.db
+chmod 660 /opt/usr/dbspace/.calendar-svc.db-journal
+chmod 660 /opt/usr/data/calendar-svc/.CALENDAR_SVC_*
+
+vconftool set -t int db/calendar/timezone_on_off 0 -g 6003
+vconftool set -t string db/calendar/timezone_path "Asia/Seoul" -g 6003
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest calendar-service.manifest
+%defattr(-,root,root,-)
+%{_bindir}/calendar-svc-initdb
+%{_libdir}/libcalendar-service-native.so.*
+%{_bindir}/calendar-serviced*
+%{_libdir}/libcalendar-service2.so.*
+%attr(0755,root,root) /etc/rc.d/init.d/calendar-serviced.sh
+/etc/rc.d/rc3.d/S85calendar-serviced
+/etc/rc.d/rc5.d/S85calendar-serviced
+%dir %attr(0775,root,root) /opt/usr/data/calendar-svc/
+/opt/usr/data/calendar-svc/.CALENDAR_SVC_CALENDAR_CHANGED
+/opt/usr/data/calendar-svc/.CALENDAR_SVC_EVENT_CHANGED
+/opt/usr/data/calendar-svc/.CALENDAR_SVC_TODO_CHANGED
+/usr/share/calendar-svc/dft-calendar
+%{_libdir}/systemd/user/calendar.service
+%{_libdir}/systemd/user/tizen-middleware.target.wants/calendar.service
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/calendar-service-native/*.h
+%{_includedir}/calendar-service2/*.h
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/calendar.pc
+%{_libdir}/pkgconfig/calendar-service-native.pc
+%{_libdir}/pkgconfig/calendar-service2.pc
diff --git a/packaging/calendar.service b/packaging/calendar.service
new file mode 100644 (file)
index 0000000..29485fe
--- /dev/null
@@ -0,0 +1,12 @@
+[Unit]
+Description=Calendar service
+
+[Service]
+Type=simple
+ExecStart=/usr/bin/calendar-serviced
+Restart=always
+RestartSec=2
+
+[Install]
+WantedBy=tizen-middleware.target
+
index 96aff0f..76515d5 100755 (executable)
@@ -1,5 +1,3 @@
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
-INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src)
 LINK_DIRECTORIES(${CMAKE_BINARY_DIR})
 
 SET(TARGET calendar-svc-initdb)
index 123460b..5e7a238 100755 (executable)
@@ -1,7 +1,7 @@
 #
 # Calendar Service
 #
-# Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+# Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
index 6836a30..30c4257 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * Calendar Service
  *
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 0767003..36f3763 100755 (executable)
@@ -1,7 +1,7 @@
 /*
  * Calendar Service
  *
- * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 #include <db-util.h>
 
 #include "schema.h"
-#include "cals-db-info.h"
-#include "cals-internal.h"
-#include "calendar-svc-errors.h"
 
+#define CALS_DB_PATH "/opt/usr/dbspace/.calendar-svc.db"
+#define CALS_DB_JOURNAL_PATH "/opt/usr/dbspace/.calendar-svc.db-journal"
+
+// For Security
+#define CALS_SECURITY_FILE_GROUP 6003
+#define CALS_SECURITY_DEFAULT_PERMISSION 0660
+#define CALS_SECURITY_DIR_DEFAULT_PERMISSION 0770
 
 static inline int remake_db_file()
 {
@@ -36,41 +40,68 @@ static inline int remake_db_file()
        sqlite3 *db;
 
        ret = db_util_open(CALS_DB_PATH, &db, 0);
-       retvm_if(SQLITE_OK != ret, CAL_ERR_DB_NOT_OPENED, "db_util_open() Failed(%d)", ret);
+       if (SQLITE_OK != ret)
+       {
+               printf("db_util_open() Failed(%d)\n", ret);
+               return -1;
+       }
 
        ret = sqlite3_exec(db, schema_query, NULL, 0, &errmsg);
        if (SQLITE_OK != ret) {
-               ERR("remake calendar DB file is Failed : %s", errmsg);
+               printf("remake calendar DB file is Failed : %s\n", errmsg);
                sqlite3_free(errmsg);
        }
 
        db_util_close(db);
 
        fd = open(CALS_DB_PATH, O_CREAT | O_RDWR, 0660);
-       retvm_if(-1 == fd, CAL_ERR_FAIL, "open Failed");
+       if (-1 == fd)
+       {
+               printf("open Failed\n");
+               return -1;
+       }
 
-       fchown(fd, getuid(), CALS_SECURITY_FILE_GROUP);
+       ret = fchown(fd, getuid(), CALS_SECURITY_FILE_GROUP);
+       if (-1 == ret)
+       {
+               printf("Failed to fchown\n");
+               close(fd);
+               return -1;
+       }
        fchmod(fd, CALS_SECURITY_DEFAULT_PERMISSION);
        close(fd);
 
        fd = open(CALS_DB_JOURNAL_PATH, O_CREAT | O_RDWR, 0660);
-       retvm_if(-1 == fd, CAL_ERR_FAIL, "open Failed");
+       if (-1 == fd)
+       {
+               printf("open Failed\n");
+               return -1;
+       }
 
-       fchown(fd, getuid(), CALS_SECURITY_FILE_GROUP);
+       ret = fchown(fd, getuid(), CALS_SECURITY_FILE_GROUP);
+       if (-1 == ret)
+       {
+               printf("Failed to fchown\n");
+               close(fd);
+               return -1;
+       }
        fchmod(fd, CALS_SECURITY_DEFAULT_PERMISSION);
        close(fd);
 
-       return CAL_SUCCESS;
+       return 0;
 }
 
 static inline int check_db_file(void)
 {
        int fd = open(CALS_DB_PATH, O_RDONLY);
-       retvm_if(-1 == fd, -1,
-                       "DB file(%s) is not exist", CALS_DB_PATH);
+       if (-1 == fd)
+       {
+               printf("DB file(%s) is not exist\n", CALS_DB_PATH);
+               return -1;
+       }
 
        close(fd);
-       return CAL_SUCCESS;
+       return 0;
 }
 
 static inline int check_schema(void)
@@ -78,7 +109,7 @@ static inline int check_schema(void)
        if (check_db_file())
                remake_db_file();
 
-       return CAL_SUCCESS;
+       return 0;
 }
 
 int main(int argc, char **argv)
index c8b4960..8900e2a 100755 (executable)
@@ -1,7 +1,7 @@
 --
 -- Calendar Service
 --
--- Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+-- Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
 --
 -- Licensed under the Apache License, Version 2.0 (the "License");
 -- you may not use this file except in compliance with the License.
@@ -21,65 +21,112 @@ CREATE TABLE schedule_table
 id INTEGER PRIMARY KEY AUTOINCREMENT,
 account_id INTEGER,
 type INTEGER,
-category INTEGER,
 summary TEXT,
 description TEXT,
 location TEXT,
-all_day_event INTEGER,
-start_date_time INTEGER,
-end_date_time INTEGER,
-repeat_item INTEGER,
-repeat_interval INTEGER,
-repeat_occurrences INTEGER,
-repeat_end_date INTEGER,
-sun_moon INTEGER,
-week_start INTEGER,
-week_flag TEXT,
-day_date INTEGER,
-last_modified_time INTEGER,
-missed INTEGER,
+categories TEXT,
+exdate TEXT,
 task_status INTEGER,
 priority INTEGER,
-timezone INTEGER,
-file_id INTEGER,
+timezone INTEGER DEFAULT 0,
 contact_id INTEGER,
 busy_status INTEGER,
 sensitivity INTEGER,
 uid TEXT,
-calendar_type INTEGER,
 organizer_name TEXT,
 organizer_email TEXT,
 meeting_status INTEGER,
-gcal_id TEXT,
-deleted INTEGER,
-updated TEXT,
-location_type INTEGER,
-location_summary TEXT,
-etag TEXT,
 calendar_id INTEGER,
-sync_status INTEGER,
-edit_uri TEXT,
-gevent_id TEXT,
-dst INTEGER,
-original_event_id INTEGER,
+original_event_id INTEGER DEFAULT -1,
 latitude DOUBLE,
 longitude DOUBLE,
-is_deleted INTEGER,
-tz_name TEXT,
-tz_city_name TEXT,
 email_id INTEGER,
 availability INTEGER,
-created_date_time INTEGER,
-completed_date_time INTEGER,
-progress INTEGER
+created_time INTEGER,
+completed_time INTEGER,
+progress INTEGER,
+changed_ver INTEGER,
+created_ver INTEGER,
+is_deleted INTEGER DEFAULT 0,
+dtstart_type INTEGER,
+dtstart_utime INTEGER,
+dtstart_datetime TEXT,
+dtstart_tzid TEXT,
+dtend_type INTEGER,
+dtend_utime INTEGER,
+dtend_datetime TEXT,
+dtend_tzid TEXT,
+last_mod INTEGER,
+rrule_id INTEGER DEFAULT 0,
+recurrence_id TEXT,
+rdate TEXT,
+has_attendee INTEGER,
+has_alarm INTEGER,
+system_type INTEGER,
+updated INTEGER,
+sync_data1 TEXT,
+sync_data2 TEXT,
+sync_data3 TEXT,
+sync_data4 TEXT
 );
-CREATE INDEX sch_idx1 ON schedule_table(type, category);
+CREATE INDEX sch_idx1 ON schedule_table(type);
 CREATE TRIGGER trg_sch_del AFTER DELETE ON schedule_table
  BEGIN
-   DELETE FROM cal_alarm_table WHERE event_id = old.id;
+   DELETE FROM rrule_table WHERE event_id = old.id;
+   DELETE FROM alarm_table WHERE event_id = old.id;
+   DELETE FROM schedule_table WHERE original_event_id = old.id;
+   DELETE FROM normal_instance_table WHERE event_id = old.id;
+   DELETE FROM allday_instance_table WHERE event_id = old.id;
+   DELETE FROM attendee_table WHERE event_id = old.id;
+   DELETE FROM extended_table WHERE record_id = old.id AND record_type = 2;
+   DELETE FROM extended_table WHERE record_id = old.id AND record_type = 3;
+ END;
+
+CREATE TRIGGER trig_original_mod AFTER UPDATE OF is_deleted ON schedule_table
+ BEGIN
+   DELETE FROM normal_instance_table WHERE event_id = (SELECT rowid FROM schedule_table WHERE original_event_id = old.id);
+   DELETE FROM allday_instance_table WHERE event_id = (SELECT rowid FROM schedule_table WHERE original_event_id = old.id);
+   UPDATE schedule_table SET is_deleted = 1 WHERE original_event_id = old.id;
  END;
 
-CREATE TABLE cal_participant_table
+CREATE TABLE rrule_table
+(
+id INTEGER PRIMARY KEY AUTOINCREMENT,
+event_id INTEGER,
+freq INTEGER DEFAULT 0,
+range_type INTEGER,
+until_type INTEGER,
+until_utime INTEGER,
+until_datetime TEXT,
+count INTEGER,
+interval INTEGER,
+bysecond TEXT,
+byminute TEXT,
+byhour TEXT,
+byday TEXT,
+bymonthday TEXT,
+byyearday TEXT,
+byweekno TEXT,
+bymonth TEXT,
+bysetpos TEXT,
+wkst INTEGER
+);
+
+CREATE TABLE normal_instance_table
+(
+event_id INTEGER,
+dtstart_utime INTEGER,
+dtend_utime INTEGER
+);
+
+CREATE TABLE allday_instance_table
+(
+event_id INTEGER,
+dtstart_datetime TEXT,
+dtend_datetime TEXT
+);
+
+CREATE TABLE attendee_table
 (
 event_id INTEGER,
 attendee_name TEXT,
@@ -96,69 +143,30 @@ attendee_delegate_uri TEXT,
 attendee_uid TEXT
 );
 
-CREATE TABLE cal_meeting_category_table
-(
-event_id INTEGER,
-category_name TEXT
-);
-
-CREATE TABLE recurrency_log_table
-(
-uid TEXT,
-start_date_time INTEGER,
-end_date_time INTEGER,
-event_id INTEGER,
-exception_event_id INTEGER,
-updated INTEGER
-);
-
 CREATE TABLE calendar_table
 (
-calendar_id TEXT,
+id INTEGER PRIMARY KEY AUTOINCREMENT,
 uid TEXT,
-link TEXT,
 updated INTEGER,
 name TEXT,
 description TEXT,
-author TEXT,
 color TEXT,
-hidden INTEGER,
-selected INTEGER,
 location TEXT,
-locale INTEGER,
-country INTEGER,
-time_zone INTEGER,
-timezone_label TEXT,
-display_all_timezones INTEGER,
-date_field_order INTEGER,
-format_24hour_time INTEGER,
-week_start INTEGER,
-default_cal_mode INTEGER,
-custom_cal_mode INTEGER,
-user_location TEXT,
-weather TEXT,
-show_declined_events INTEGER,
-hide_invitations INTEGER,
-alternate_calendar INTEGER,
 visibility INTEGER,
-projection INTEGER,
-sequence INTEGER,
-suppress_reply_notifications INTEGER,
 sync_event INTEGER,
-times_cleaned INTEGER,
-guests_can_modify INTEGER,
-guests_can_invite_others INTEGER,
-guests_can_see_guests INTEGER,
-access_level INTEGER,
-sync_status INTEGER,
-is_deleted INTEGER,
+is_deleted INTEGER DEFAULT 0,
 account_id INTEGER,
-sensitivity INTEGER,
-store_type INTEGER
+store_type INTEGER,
+sync_data1 TEXT,
+sync_data2 TEXT,
+sync_data3 TEXT,
+sync_data4 TEXT,
+deleted INTEGER DEFAULT 0
 );
 
 CREATE TABLE timezone_table
 (
+id INTEGER PRIMARY KEY AUTOINCREMENT,
 tz_offset_from_gmt INTEGER,
 standard_name TEXT,
 std_start_month INTEGER,
@@ -171,10 +179,18 @@ day_light_start_month INTEGER,
 day_light_start_position_of_week INTEGER,
 day_light_start_day INTEGER,
 day_light_start_hour INTEGER,
-day_light_bias INTEGER
+day_light_bias INTEGER,
+calendar_id INTEGER
 );
 
-CREATE TABLE cal_alarm_table
+CREATE TRIGGER trg_cal_del AFTER DELETE ON calendar_table
+ BEGIN
+   DELETE FROM timezone_table WHERE calendar_id = old.id;
+   DELETE FROM schedule_table WHERE calendar_id = old.id;
+   DELETE FROM extended_table WHERE record_id = old.id AND record_type = 1;
+ END;
+
+CREATE TABLE alarm_table
 (
 event_id INTEGER,
 alarm_time INTEGER,
@@ -183,7 +199,42 @@ remind_tick_unit INTEGER,
 alarm_tone TEXT,
 alarm_description TEXT,
 alarm_type INTEGER,
-alarm_id INTEGER
+alarm_id INTEGER default 0
+);
+
+CREATE TABLE reminder_table
+(
+pkgname TEXT NOT NULL,
+onoff INTEGER default 1,
+key TEXT,
+value TEXT
+);
+INSERT INTO reminder_table VALUES('org.tizen.calendar', 1, NULL, NULL);
+
+CREATE TABLE extended_table
+(
+id INTEGER PRIMARY KEY AUTOINCREMENT,
+record_id INTEGER,
+record_type INTEGER,
+key TEXT,
+value TEXT
+);
+
+CREATE TABLE deleted_table
+(
+schedule_id INTEGER,
+schedule_type INTEGER,
+calendar_id INTEGER,
+deleted_ver INTEGER
+);
+CREATE INDEX deleted_schedule_ver_idx ON deleted_table(deleted_ver);
+
+CREATE TABLE version_table
+(
+ver INTEGER PRIMARY KEY
 );
+INSERT INTO version_table VALUES(0);
 
-INSERT INTO calendar_table VALUES(0,0,0,0,'default calendar',0,0,'76.198.86.255',0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,-1,0,3);
+INSERT INTO calendar_table VALUES(1,0,0,'Default event calendar'   ,0,'224.167.79.255',0,1,1,0,-1,1,0,0,0,0,0);
+INSERT INTO calendar_table VALUES(2,0,0,'Default todo calendar'    ,0,'41.177.227.255',0,1,1,0,-1,2,0,0,0,0,0);
+INSERT INTO calendar_table VALUES(3,0,0,'Default birthday calendar',0,'141.17.27.255' ,0,1,0,0,-1,1,0,0,0,0,0);
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
new file mode 100755 (executable)
index 0000000..c7704fd
--- /dev/null
@@ -0,0 +1,95 @@
+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 calendar-serviced)
+SET(LIBNAME calendar-service-server)
+
+SET(LIBSRCS
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_alarm.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_attendee.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_calendar.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_event.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_instance_allday.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_instance_normal.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_search.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_timezone.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_todo.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_updated_info.c
+       ${CMAKE_SOURCE_DIR}/common/ipc/cal_ipc_marshal_extended.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_calendar.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_event.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_todo.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_attendee.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_alarm.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_search.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_timezone.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_updated_info.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_instance_normal.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_instance_allday.c
+       ${CMAKE_SOURCE_DIR}/common/cal_record_extended.c
+       ${CMAKE_SOURCE_DIR}/common/cal_view.c
+       ${CMAKE_SOURCE_DIR}/common/cal_filter.c
+       ${CMAKE_SOURCE_DIR}/common/cal_query.c
+       ${CMAKE_SOURCE_DIR}/common/cal_list.c
+       ${CMAKE_SOURCE_DIR}/common/cal_time.cpp
+       ${CMAKE_SOURCE_DIR}/common/cal_inotify.c
+    ${CMAKE_SOURCE_DIR}/common/cal_vcalendar.c
+    ${CMAKE_SOURCE_DIR}/common/cal_vcalendar_make.c
+    ${CMAKE_SOURCE_DIR}/common/cal_vcalendar_parse.c
+       ${CMAKE_SOURCE_DIR}/common/cal_mutex.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db.c
+       ${CMAKE_SOURCE_DIR}/native/cal_calendar.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_util.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_alarm.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_attendee.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_instance.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_rrule.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_query.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_calendar.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_event.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_search.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_timezone.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_instance_normal.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_instance_allday.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_todo.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_plugin_extended.c
+       ${CMAKE_SOURCE_DIR}/native/cal_db_extended.c
+       ${CMAKE_SOURCE_DIR}/native/cal_reminder.c
+       cal_server_ipc.c
+)
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(calserver_pkgs REQUIRED pims-ipc db-util appsvc alarm-service capi-base-common icu-i18n alarm-service)
+
+FOREACH(flag ${calserver_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}")
+SET(calserver_pkgs_LDFLAGS "${pkgs_LDFLAGS} ${calserver_pkgs_LDFLAGS}")
+
+ADD_DEFINITIONS("-DCAL_IPC_SERVER")
+ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"")
+
+ADD_LIBRARY(${LIBNAME} STATIC ${LIBSRCS})
+TARGET_LINK_LIBRARIES(${LIBNAME} ${calserver_pkgs_LDFLAGS})
+
+#cmake_policy(SET CMP0002 OLD)
+ADD_EXECUTABLE(${DAEMON}
+       cal_server.c
+       cal_server_alarm.c
+       cal_server_calendar_delete.c
+       )
+SET_TARGET_PROPERTIES(${DAEMON} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS})
+TARGET_LINK_LIBRARIES(${DAEMON} ${calserver_pkgs_LDFLAGS} ${LIBNAME})
+
+INSTALL(TARGETS ${DAEMON} DESTINATION bin)
+INSTALL(PROGRAMS ${CMAKE_CURRENT_SOURCE_DIR}/calendar-serviced.sh DESTINATION /etc/rc.d/init.d)
diff --git a/server/cal_server.c b/server/cal_server.c
new file mode 100644 (file)
index 0000000..2c72329
--- /dev/null
@@ -0,0 +1,213 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <glib-object.h>
+
+#include "calendar2.h"
+#include "cal_ipc.h"
+#include "cal_server_ipc.h"
+#include "cal_typedef.h"
+#include "cal_inotify.h"
+
+#include "cal_db.h" // CAL_SECURITY_FILE_GROUP
+#include "cal_internal.h" // DBG
+
+#include "cal_server_alarm.h"
+#include "cal_server_calendar_delete.h"
+
+//static GMainLoop *loop;
+
+static int __server_main();
+
+static int __server_main(void)
+{
+       int ret;
+    g_type_init();
+
+    pims_ipc_svc_init(CAL_IPC_SOCKET_PATH,CAL_SECURITY_FILE_GROUP,CAL_SECURITY_DEFAULT_PERMISSION);
+
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_CONNECT, _cal_server_ipc_connect, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DISCONNECT, _cal_server_ipc_disconnect, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_INSERT_RECORD, _cal_server_ipc_db_insert_record, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_RECORD, _cal_server_ipc_db_get_record, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_UPDATE_RECORD, _cal_server_ipc_db_update_record, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_DELETE_RECORD, _cal_server_ipc_db_delete_record, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_ALL_RECORDS, _cal_server_ipc_db_get_all_records, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_RECORDS_WITH_QUERY, _cal_server_ipc_db_get_records_with_query, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_CLEAN_AFTER_SYNC, _cal_server_ipc_db_clean_after_sync, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_COUNT, _cal_server_ipc_db_get_count, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_COUNT_WITH_QUERY, _cal_server_ipc_db_get_count_with_query, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_INSERT_RECORDS, _cal_server_ipc_db_insert_records, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_UPDATE_RECORDS, _cal_server_ipc_db_update_records, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_DELETE_RECORDS, _cal_server_ipc_db_delete_records, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_CHANGES_BY_VERSION, _cal_server_ipc_db_get_changes_by_version, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_GET_CURRENT_VERSION, _cal_server_ipc_db_get_current_version, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_INSERT_VCALENDARS, _cal_server_ipc_db_insert_vcalendars, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REPLACE_VCALENDARS, _cal_server_ipc_db_replace_vcalendars, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REPLACE_RECORD, _cal_server_ipc_db_replace_record, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REPLACE_RECORDS, _cal_server_ipc_db_replace_records, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_REGISTER_REMINDER, _cal_server_ipc_db_register_reminder, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_UNREGISTER_REMINDER, _cal_server_ipc_db_unregister_reminder, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_ACTIVATE_REMINDER, _cal_server_ipc_db_activate_reminder, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_DEACTIVATE_REMINDER, _cal_server_ipc_db_deactivate_reminder, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+    if (pims_ipc_svc_register(CAL_IPC_MODULE, CAL_IPC_SERVER_DB_HAS_REMINDER, _cal_server_ipc_db_has_reminder, NULL) != 0)
+    {
+        ERR("pims_ipc_svc_register error");
+        return -1;
+    }
+
+    //loop = g_main_loop_new(NULL, FALSE);
+
+    //calendar_alarm_init();
+
+       ret = calendar_connect();
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("calendar_connect() failed");
+               return ret;
+       }
+
+       _cal_inotify_initialize();
+       ret = _cal_server_alarm();
+       if (CALENDAR_ERROR_NONE != ret)
+       {
+               ERR("_cal_server_alarm() failed");
+               return -1;
+       }
+
+       _cal_server_calendar_delete_start();
+
+    pims_ipc_svc_run_main_loop(NULL);
+
+       _cal_inotify_finalize();
+       calendar_disconnect();
+
+    pims_ipc_svc_deinit();
+
+    return 0;
+}
+
+int main(int argc, char *argv[])
+{
+    __server_main();
+    return 0;
+}
+
diff --git a/server/cal_server_alarm.c b/server/cal_server_alarm.c
new file mode 100644 (file)
index 0000000..d54edec
--- /dev/null
@@ -0,0 +1,1024 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <appsvc.h>
+#include <alarm.h>
+#include <vconf.h>
+
+#include "cal_internal.h"
+#include "calendar2.h"
+#include "cal_time.h"
+#include "cal_typedef.h"
+#include "cal_inotify.h"
+
+#include "cal_db_util.h"
+#include "cal_db.h"
+#include "cal_db_query.h"
+
+static struct timeval stv; // check time
+static struct timeval etv; // check time
+
+static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id);
+
+static int __cal_server_alarm_clear_all_cb(alarm_id_t alarm_id, void *data)
+{
+       int ret;
+
+       DBG("remove alarm id(%d)", alarm_id);
+       __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
+       ret = alarmmgr_remove_alarm(alarm_id);
+       if (ret != ALARMMGR_RESULT_SUCCESS)
+       {
+               ERR("alarmmgr_remove_alarm() failed(ret:%d)", ret);
+               return ret;
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+struct _normal_data_s
+{
+       int id;
+       long long int alarm_utime;
+       int tick;
+       int unit;
+       int alarm_id;
+};
+
+struct _allday_data_s
+{
+       int id;
+       int alarm_datetime;
+       int tick;
+       int unit;
+       int alarm_id;
+};
+
+static int __cal_server_alarm_get_next_list_normal_event(long long int from_utime, long long int to_utime, GList **list, int *count)
+{
+       int index;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+       DBG("searching normal event (%lld) ~ (%lld)", from_utime, to_utime);
+
+       snprintf(query, sizeof(query),
+                       "SELECT A.event_id, B.alarm_time, "
+                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
+                       "FROM %s as A, "                       // A is normal instance
+                       "%s as B ON A.event_id = B.event_id, " // B is alarm
+                       "%s as C ON B.event_id = C.id "        // c is schedule
+                       "WHERE C.has_alarm == 1 AND C.type = %d "
+                       "AND B.remind_tick_unit = %d AND B.alarm_time = %lld "
+                       "UNION "
+                       "SELECT A.event_id, A.dtstart_utime - (B.remind_tick * B.remind_tick_unit), "
+                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
+                       "FROM %s as A, "                       // A is normal instance
+                       "%s as B ON A.event_id = B.event_id, " // B is alarm
+                       "%s as C ON B.event_id = C.id "        // c is schedule
+                       "WHERE C.has_alarm = 1 AND C.type = %d "
+                       "AND B.remind_tick_unit > %d "
+                       "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
+                       "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
+                       "ORDER BY (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit))",
+                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
+                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       from_utime, to_utime);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       *count = 0;
+       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
+       {
+               struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
+
+               index = 0;
+               nd->id = sqlite3_column_int(stmt, index++);
+               nd->alarm_utime = sqlite3_column_int64(stmt, index++);
+               nd->tick = sqlite3_column_int(stmt, index++);
+               nd->unit = sqlite3_column_int(stmt, index++);
+               nd->alarm_id = sqlite3_column_int(stmt, index++);
+
+               *list = g_list_append(*list, nd);
+               (*count)++;
+       }
+       sqlite3_finalize(stmt);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_get_next_list_normal_todo(long long int from_utime, long long int to_utime, GList **list, int *count)
+{
+       int index;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+       DBG("searching normal todo (%lld) ~ (%lld)", from_utime, to_utime);
+
+       snprintf(query, sizeof(query),
+                       "SELECT B.id, A.alarm_time, "
+                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
+                       "FROM %s as A, "                          // A is alarm
+                       "%s as B ON A.event_id = B.id "           // B is schedule
+                       "WHERE B.has_alarm == 1 AND B.type = %d "
+                       "AND A.remind_tick_unit = %d AND A.alarm_time = %lld "
+                       "UNION "
+                       "SELECT B.id, B.dtend_utime - (A.remind_tick * A.remind_tick_unit), "
+                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
+                       "FROM %s as A, "                          // A is alarm
+                       "%s as B ON A.event_id = B.id "           // B is schedule
+                       "WHERE B.has_alarm = 1 AND B.type = %d "
+                       "AND A.remind_tick_unit > %d "
+                       "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
+                       "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld "
+                       "ORDER BY (B.dtend_utime - (A.remind_tick * A.remind_tick_unit))",
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_utime,
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       from_utime, to_utime);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       *count = 0;
+       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
+       {
+               struct _normal_data_s *nd = calloc(1, sizeof(struct _normal_data_s));
+
+               index = 0;
+               nd->id = sqlite3_column_int(stmt, index++);
+               nd->alarm_utime = sqlite3_column_int64(stmt, index++);
+               nd->tick = sqlite3_column_int(stmt, index++);
+               nd->unit = sqlite3_column_int(stmt, index++);
+               nd->alarm_id = sqlite3_column_int(stmt, index++);
+
+               *list = g_list_append(*list, nd);
+               (*count)++;
+       }
+       sqlite3_finalize(stmt);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_get_next_list_allday_event(int from_datetime, int to_datetime, GList **list, int *count)
+{
+       int index;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+       DBG("searching allday (%d) ~ (%d)", from_datetime, to_datetime);
+
+       snprintf(query, sizeof(query),
+                       "SELECT A.event_id, B.alarm_time, "
+                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
+                       "FROM %s as A, "                       // A is allday instance
+                       "%s as B ON A.event_id = B.event_id, " // B is alarm
+                       "%s as C ON B.event_id = C.id "        // C is schedule
+                       "WHERE C.has_alarm == 1 AND C.type = %d "
+                       "AND B.remind_tick_unit = %d AND B.alarm_time = %d "
+                       "UNION "
+                       "SELECT A.event_id, A.dtstart_datetime, "
+                       "B.remind_tick, B.remind_tick_unit, B.alarm_id "
+                       "FROM %s as A, "                       // A is allday instance
+                       "%s as B ON A.event_id = B.event_id, " // B is alarm
+                       "%s as C ON B.event_id = C.id "        // C is schedule
+                       "WHERE C.has_alarm = 1 AND C.type = %d "
+                       "AND B.remind_tick_unit > %d "
+                       "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 > %d "
+                       "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 <= %d ",
+                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
+                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       from_datetime, to_datetime);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       *count = 0;
+       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
+       {
+               struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
+
+               index = 0;
+               ad->id = sqlite3_column_int(stmt, index++);
+               ad->alarm_datetime = sqlite3_column_int(stmt, index++);
+               ad->tick = sqlite3_column_int(stmt, index++);
+               ad->unit = sqlite3_column_int(stmt, index++);
+               ad->alarm_id = sqlite3_column_int(stmt, index++);
+
+               *list = g_list_append(*list, ad);
+               (*count)++;
+       }
+       sqlite3_finalize(stmt);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_get_next_list_allday_todo(int from_datetime, int to_datetime, GList **list, int *count)
+{
+       int index;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+       DBG("searching allday todo(%d) ~ (%d)", from_datetime, to_datetime);
+
+       snprintf(query, sizeof(query),
+                       "SELECT A.event_id, A.alarm_time, "
+                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
+                       "FROM %s as A, "                // A is alarm
+                       "%s as B ON A.event_id = B.id " // B is schedule
+                       "WHERE B.has_alarm == 1 AND B.type = %d "
+                       "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
+                       "UNION "
+                       "SELECT A.event_id, B.dtend_datetime, "
+                       "A.remind_tick, A.remind_tick_unit, A.alarm_id "
+                       "FROM %s as A, "                // A is alarm
+                       "%s as B ON A.event_id = B.id " // B is schedule
+                       "WHERE B.has_alarm = 1 AND B.type = %d "
+                       "AND A.remind_tick_unit > %d "
+                       "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 > %d "
+                       "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 <= %d ",
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, from_datetime,
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       from_datetime, to_datetime);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       *count = 0;
+       while (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
+       {
+               struct _allday_data_s *ad = calloc(1, sizeof(struct _allday_data_s));
+
+               index = 0;
+               ad->id = sqlite3_column_int(stmt, index++);
+               ad->alarm_datetime = sqlite3_column_int(stmt, index++);
+               ad->tick = sqlite3_column_int(stmt, index++);
+               ad->unit = sqlite3_column_int(stmt, index++);
+               ad->alarm_id = sqlite3_column_int(stmt, index++);
+
+               *list = g_list_append(*list, ad);
+               (*count)++;
+       }
+       sqlite3_finalize(stmt);
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_update_alarm_id(int alarm_id, int event_id, int tick, int unit)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       DBG("Update alarm_id(%d) in alarm table", alarm_id);
+       snprintf(query, sizeof(query), "UPDATE %s SET "
+                       "alarm_id = %d "
+                       "WHERE event_id = %d AND remind_tick = %d AND remind_tick_unit = %d",
+                       CAL_TABLE_ALARM,
+                       alarm_id,
+                       event_id, tick, unit);
+
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static GFunc __cal_server_alarm_print_list_normal(gpointer data, gpointer user_data)
+{
+       struct _normal_data_s *normal = (struct _normal_data_s *)data;
+       DBG("%02d:%lld", normal->id, normal->alarm_utime);
+       return 0;
+}
+
+static GFunc __cal_server_alarm_print_list_allday_todo(gpointer data, gpointer user_data)
+{
+       struct _allday_data_s *allday = (struct _allday_data_s *)data;
+       DBG("%02d:%d", allday->id, allday->alarm_datetime);
+       return 0;
+}
+
+static int __cal_server_alarm_get_list_with_alarmmgr_id(int alarm_id, GList **normal_list, GList **allday_list)
+{
+       int index;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+       struct _normal_data_s *nd;
+       struct _allday_data_s *ad;
+
+       snprintf(query, sizeof(query),
+                       "SELECT A.type, A.dtstart_type, A.dtend_type, B.remind_tick, B.remind_tick_unit "
+                       "FROM %s as A, "                // schedule
+                       "%s as B ON A.id = B.event_id " // alarm
+                       "WHERE B.alarm_id = %d",
+                       CAL_TABLE_SCHEDULE,
+                       CAL_TABLE_ALARM,
+                       alarm_id);
+
+       stmt = _cal_db_util_query_prepare(query);
+       if (NULL == stmt)
+       {
+               DBG("query[%s]", query);
+               ERR("_cal_db_util_query_prepare() Failed");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       int type = 0;
+       int dtstart_type = 0;
+       int dtend_type = 0;
+       int tick = 0;
+       int unit = 0;
+       if (CAL_DB_ROW  == _cal_db_util_stmt_step(stmt))
+       {
+               index = 0;
+               type = sqlite3_column_int(stmt, index++);
+               dtstart_type = sqlite3_column_int(stmt, index++);
+               dtend_type = sqlite3_column_int(stmt, index++);
+               tick = sqlite3_column_int(stmt, index++);
+               unit = sqlite3_column_int(stmt, index++);
+       }
+       else
+       {
+               ERR("No record");
+       }
+       sqlite3_finalize(stmt);
+       stmt = NULL;
+
+       if ((type == CALENDAR_BOOK_TYPE_EVENT && dtstart_type == CALENDAR_TIME_UTIME)
+                       || (type == CALENDAR_BOOK_TYPE_TODO && dtend_type == CALENDAR_TIME_UTIME))
+       {
+               long long int now_utime;
+               now_utime = _cal_time_get_now();
+               now_utime -= now_utime % 60;
+
+               snprintf(query, sizeof(query),
+                               "SELECT A.event_id, A.dtstart_utime, "
+                               "B.remind_tick, B.remind_tick_unit "
+                               "FROM %s as A, "                       // A is normal instance
+                               "%s as B ON A.event_id = B.event_id, " // B is alarm
+                               "%s as C ON B.event_id = C.id "        // c is schedule
+                               "WHERE C.has_alarm == 1 AND C.type = %d "
+                               "AND B.remind_tick_unit = %d "
+                               "AND B.alarm_time = %lld "
+                               "UNION "
+                               "SELECT A.event_id, A.dtstart_utime, "
+                               "B.remind_tick, B.remind_tick_unit "
+                               "FROM %s as A, "                       // A is normal instance
+                               "%s as B ON A.event_id = B.event_id, " // B is alarm
+                               "%s as C ON B.event_id = C.id "        // c is schedule
+                               "WHERE C.has_alarm = 1 AND C.type = %d "
+                               "AND B.remind_tick_unit > %d "
+                               "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) >= %lld "
+                               "AND (A.dtstart_utime - (B.remind_tick * B.remind_tick_unit)) < %lld "
+                               "UNION "
+                               "SELECT B.id, B.dtend_utime, "
+                               "A.remind_tick, A.remind_tick_unit "
+                               "FROM %s as A, "                          // A is alarm
+                               "%s as B ON A.event_id = B.id "           // B is schedule
+                               "WHERE B.has_alarm == 1 AND B.type = %d "
+                               "AND A.remind_tick_unit = %d "
+                               "AND A.alarm_time = %lld "
+                               "UNION "
+                               "SELECT B.id, B.dtend_utime, "
+                               "A.remind_tick, A.remind_tick_unit "
+                               "FROM %s as A, "                          // A is alarm
+                               "%s as B ON A.event_id = B.id "           // B is schedule
+                               "WHERE B.has_alarm = 1 AND B.type = %d "
+                               "AND A.remind_tick_unit > %d "
+                               "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) >= %lld "
+                               "AND (B.dtend_utime - (A.remind_tick * A.remind_tick_unit)) < %lld ",
+                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_utime,
+                       CAL_TABLE_NORMAL_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_utime, now_utime + 60,
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_utime,
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_utime, now_utime + 60);
+
+               stmt = _cal_db_util_query_prepare(query);
+               if (NULL == stmt)
+               {
+                       DBG("query[%s]", query);
+                       ERR("_cal_db_util_query_prepare() Failed");
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+
+               while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+               {
+                       index = 0;
+                       nd = calloc(1, sizeof(struct _normal_data_s));
+                       nd->id = sqlite3_column_int(stmt, index++);
+                       nd->alarm_utime = sqlite3_column_int64(stmt, index++); // dtstart, dtend
+                       nd->tick = sqlite3_column_int(stmt, index++);
+                       nd->unit = sqlite3_column_int(stmt, index++);
+                       *normal_list = g_list_append(*normal_list, nd);
+                       DBG("(%d)", nd->id);
+               }
+       }
+       else
+       {
+               int now_datetime;
+               time_t now_timet = time(NULL);
+               struct tm start_tm = {0};
+               now_timet -= now_timet % 60;
+               gmtime_r(&now_timet, &start_tm);
+               now_datetime = (start_tm.tm_year + 1900) * 10000
+                       + (start_tm.tm_mon + 1) * 100
+                       + (start_tm.tm_mday);
+
+               snprintf(query, sizeof(query),
+                               "SELECT A.event_id, A.dtstart_datetime, "
+                               "B.remind_tick, B.remind_tick_unit "
+                               "FROM %s as A, "                       // A is allday instance
+                               "%s as B ON A.event_id = B.event_id, " // B is alarm
+                               "%s as C ON B.event_id = C.id "        // C is schedule
+                               "WHERE C.has_alarm == 1 AND C.type = %d "
+                               "AND B.remind_tick_unit = %d "
+                               "AND B.alarm_time = %d "
+                               "UNION "
+                               "SELECT A.event_id, A.dtstart_datetime, "
+                               "B.remind_tick, B.remind_tick_unit "
+                               "FROM %s as A, "                       // A is allday instance
+                               "%s as B ON A.event_id = B.event_id, " // B is alarm
+                               "%s as C ON B.event_id = C.id "        // C is schedule
+                               "WHERE C.has_alarm = 1 AND C.type = %d "
+                               "AND B.remind_tick_unit > %d "
+                               "AND A.dtstart_datetime - (B.remind_tick * B.remind_tick_unit)/86400 = %d "
+                               "UNION "
+                               "SELECT A.event_id, B.dtend_datetime, "
+                               "A.remind_tick, A.remind_tick_unit "
+                               "FROM %s as A, "                // A is alarm
+                               "%s as B ON A.event_id = B.id " // B is schedule
+                               "WHERE B.has_alarm == 1 AND B.type = %d "
+                               "AND A.remind_tick_unit = %d AND A.alarm_time = %d "
+                               "UNION "
+                               "SELECT A.event_id, B.dtend_datetime, "
+                               "A.remind_tick, A.remind_tick_unit "
+                               "FROM %s as A, "                // A is alarm
+                               "%s as B ON A.event_id = B.id " // B is schedule
+                               "WHERE B.has_alarm = 1 AND B.type = %d "
+                               "AND A.remind_tick_unit > %d "
+                               "AND B.dtend_datetime - (A.remind_tick * A.remind_tick_unit)/86400 = %d ",
+                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_datetime,
+                       CAL_TABLE_ALLDAY_INSTANCE, CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_EVENT,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_datetime,
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_datetime,
+                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+                       CALENDAR_BOOK_TYPE_TODO,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       now_datetime);
+
+               stmt = _cal_db_util_query_prepare(query);
+               if (NULL == stmt)
+               {
+                       DBG("query[%s]", query);
+                       ERR("_cal_db_util_query_prepare() Failed");
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+
+               const unsigned char *temp;
+               while (CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+               {
+                       index = 0;
+                       ad = calloc(1, sizeof(struct _allday_data_s));
+                       ad->id = sqlite3_column_int(stmt, index++);
+                       temp = sqlite3_column_text(stmt, index++); // dtstart, dtend
+                       ad->alarm_datetime = atoi((const char *)temp);
+                       ad->tick = sqlite3_column_int(stmt, index++);
+                       ad->unit = sqlite3_column_int(stmt, index++);
+                       *allday_list = g_list_append(*allday_list, ad);
+               }
+       }
+       sqlite3_finalize(stmt);
+       return CALENDAR_ERROR_NONE;
+}
+
+// this api is necessary for repeat instance.
+static int __cal_server_alarm_unset_alerted_alarmmgr_id(int alarm_id)
+{
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       DBG("alarm_id(%d)", alarm_id);
+
+       snprintf(query, sizeof(query),
+                       "UPDATE %s SET alarm_id = 0 WHERE alarm_id = %d ",
+                       CAL_TABLE_ALARM, alarm_id);
+
+       dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+       {
+               ERR("_cal_db_util_query_exec() Failed(%d)", dbret);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+       }
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_alert_with_pkgname(const char *pkgname, char *id, char *time, char *tick, char *unit)
+{
+       int ret = CALENDAR_ERROR_NONE;
+       int index;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+       const char *key;
+       const char *value;
+    sqlite3_stmt *stmt = NULL;
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+       if (NULL == pkgname)
+       {
+               ERR("Invalid parameter: pkgname is NULL");
+               return CALENDAR_ERROR_INVALID_PARAMETER;
+       }
+
+       // get user key, value
+       snprintf(query, sizeof(query), "SELECT key, value FROM %s WHERE pkgname = '%s' ",
+                       CAL_REMINDER_ALERT, pkgname);
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+               index = 0;
+               key = (const char *)sqlite3_column_text(stmt, index++);
+               value = (const char *)sqlite3_column_text(stmt, index++);
+       }
+
+       // run appsvc
+       DBG("[%s][%s][%s][%s]", id, time, tick, unit);
+
+       bundle *b;
+       b = bundle_create();
+       appsvc_set_pkgname(b, pkgname);
+       appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT);
+       if (key && value) appsvc_add_data(b, key, value);
+       appsvc_add_data(b, "calendar-service/id", id);
+       appsvc_add_data(b, "calendar-service/time", time);
+       appsvc_add_data(b, "calendar-service/tick", tick);
+       appsvc_add_data(b, "calendar-service/unit", unit);
+       ret = appsvc_run_service(b, 0, NULL, NULL);
+       bundle_free(b);
+
+       sqlite3_finalize(stmt);
+
+       // if no app, delete from the table
+       if (APPSVC_RET_ELAUNCH == ret)
+       {
+               DBG("Deleted no responce pkg[%s]", pkgname);
+               snprintf(query, sizeof(query), "DELETE FROM %s WHERE pkgname = '%s' ",
+                               CAL_REMINDER_ALERT, pkgname);
+               dbret = _cal_db_util_query_exec(query);
+               if (CAL_DB_OK != dbret)
+               {
+                       ERR("_cal_db_util_query_exec() failed(ret:%d)", ret);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+               }
+
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_alert(char *id, char *time, char *tick, char *unit)
+{
+       int index;
+    char query[CAL_DB_SQL_MAX_LEN] = {0};
+    sqlite3_stmt *stmt = NULL;
+
+       snprintf(query, sizeof(query), "SELECT pkgname FROM %s WHERE onoff = 1 ",
+                       CAL_REMINDER_ALERT);
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+               index = 0;
+               const char *pkgname = (const char *)sqlite3_column_text(stmt, index++);
+               DBG("pkgname[%s]", pkgname);
+               __cal_server_alarm_alert_with_pkgname(pkgname, id, time, tick, unit);
+       }
+       sqlite3_finalize(stmt);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_noti_with_appsvc(int alarm_id, GList *normal_list, GList *allday_list)
+{
+       char buf_id[128] = {0};
+       char buf_time[128] = {0};
+       char buf_tick[128] = {0};
+       char buf_unit[128] = {0};
+       GList *l = NULL;
+
+       l = g_list_first(normal_list);
+       if (NULL == l) DBG("normal list is NULL");
+       while (l)
+       {
+               struct _normal_data_s *nd = (struct _normal_data_s *)l->data;
+               snprintf(buf_id, sizeof(buf_id), "%d", nd->id);
+               snprintf(buf_time, sizeof(buf_time), "%lld", nd->alarm_utime);
+               snprintf(buf_tick, sizeof(buf_tick), "%d", nd->tick);
+               snprintf(buf_unit, sizeof(buf_unit), "%d", nd->unit);
+
+               __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit);
+               l = g_list_next(l);
+       }
+
+       l = NULL;
+       l = g_list_first(allday_list);
+       if (NULL == l) DBG("allday list is NULL");
+       while (l)
+       {
+               struct _allday_data_s *ad = (struct _allday_data_s *)l->data;
+               snprintf(buf_id, sizeof(buf_id), "%d",  ad->id);
+               snprintf(buf_time, sizeof(buf_time), "%d", ad->alarm_datetime);
+               snprintf(buf_tick, sizeof(buf_tick), "%d", ad->tick);
+               snprintf(buf_unit, sizeof(buf_unit), "%d", ad->unit);
+
+               __cal_server_alarm_alert(buf_id, buf_time, buf_tick, buf_unit);
+               l = g_list_next(l);
+       }
+       return 0;
+}
+
+static int __cal_server_alarm_register_next_normal(long long int now_utime, GList *normal_list)
+{
+       int ret;
+       int alarm_id;
+       struct _normal_data_s *nd;
+
+       GList *l = g_list_first(normal_list);
+
+       // try to save the first record.
+       // if alarm id exists, it means updated record is not earilier than already registerd one.
+       nd = (struct _normal_data_s *)l->data;
+       if (NULL == nd)
+       {
+               ERR("No data");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       if (nd->alarm_id > 0)
+       {
+               DBG("Already registered this id");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       DBG("new is earilier than registered.");
+
+       // clear all alarm which set by mine.
+       ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
+       if (ret != ALARMMGR_RESULT_SUCCESS)
+       {
+               ERR("alarmmgr_enum_alarm_ids() failed");
+               return ret;
+       }
+
+       // register new list
+       long long int mod_alarm_utime; // del seconds
+       mod_alarm_utime = nd->alarm_utime - (nd->alarm_utime % 60);
+       ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE,
+                       (time_t)(mod_alarm_utime - now_utime),
+                       0, NULL, &alarm_id);
+       if (ret < 0)
+       {
+               ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
+               return ret;
+       }
+       DBG("Get normal alarmmgr id (%d)", alarm_id);
+       __cal_server_alarm_update_alarm_id(alarm_id, nd->id, nd->tick, nd->unit);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_alarm_register_next_allday(time_t now_timet, GList *allday_list)
+{
+       int ret;
+       int alarm_id;
+       struct _allday_data_s *ad;
+       time_t alarm_timet;
+
+       GList *l = g_list_first(allday_list);
+       alarm_id = 0;
+       ad = (struct _allday_data_s *)l->data;
+       if (NULL == ad)
+       {
+               ERR("No data");
+               return CALENDAR_ERROR_DB_FAILED;
+       }
+
+       if (ad->alarm_id > 0)
+       {
+               DBG("Already registered this id");
+               return CALENDAR_ERROR_NONE;
+       }
+
+       DBG("new is earilier than registered.");
+
+       // clear all alarm which set by mine.
+       ret = alarmmgr_enum_alarm_ids(__cal_server_alarm_clear_all_cb, NULL);
+       if (ret != ALARMMGR_RESULT_SUCCESS)
+       {
+               ERR("alarmmgr_enum_alarm_ids() failed");
+               return ret;
+       }
+
+       // register new list
+       ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE,
+                       (time_t)(alarm_timet - (ad->tick * ad->unit) - now_timet),
+                       0, NULL, &alarm_id);
+       if (ret < 0)
+       {
+               ERR("alarmmgr_add_alarm_appsvc failed (%d)", ret);
+               return ret;
+       }
+       DBG("Get allday alarmmgr id (%d)", alarm_id);
+       __cal_server_alarm_update_alarm_id(alarm_id, ad->id, ad->tick, ad->unit);
+
+       return CALENDAR_ERROR_NONE;
+}
+
+static gint __cal_server_alarm_normal_sort_cb(gconstpointer a, gconstpointer b)
+{
+       struct _normal_data_s *p1 = (struct _normal_data_s *)a;
+       struct _normal_data_s *p2 = (struct _normal_data_s *)b;
+
+       return p1->alarm_utime - p2->alarm_utime > 0 ? 1 : -1;
+}
+
+static gint __cal_server_alarm_allday_sort_cb(gconstpointer a, gconstpointer b)
+{
+       struct _allday_data_s *p1 = (struct _allday_data_s *)a;
+       struct _allday_data_s *p2 = (struct _allday_data_s *)b;
+
+       return p1->alarm_datetime - p2->alarm_datetime > 0 ? 1 : -1;
+}
+
+static int __cal_server_alarm_register_with_alarmmgr(void)
+{
+       GList *normal_list = NULL;
+       GList *allday_list = NULL;
+       int event_count;
+       int todo_count;
+       int loop_count;
+
+       gettimeofday(&stv, NULL); // check time
+
+       // for normal
+       long long int now_utime;
+       long long int from_utime, to_utime;
+       now_utime = _cal_time_get_now();
+
+       event_count = 0;
+       todo_count = 0;
+       to_utime = now_utime - (now_utime %  60) + 60;
+
+       // searching 3months, next 6months, next 12months
+       for (loop_count = 1; loop_count < 4; loop_count++)
+       {
+               from_utime = to_utime;
+               to_utime = from_utime + (60 * 60 * 24 * 30 * 3 * loop_count);
+               __cal_server_alarm_get_next_list_normal_event(from_utime, to_utime, &normal_list, &event_count);
+               __cal_server_alarm_get_next_list_normal_todo(from_utime, to_utime, &normal_list, &todo_count);
+               if (event_count + todo_count > 0)
+               {
+                       break;
+               }
+       }
+       DBG("event count(%d) todo count(%d)", event_count, todo_count);
+
+       if (event_count + todo_count > 0)
+       {
+               normal_list = g_list_sort(normal_list, __cal_server_alarm_normal_sort_cb);
+               DBG("after sorting");
+               g_list_foreach(normal_list, (GFunc)__cal_server_alarm_print_list_normal, NULL);
+               __cal_server_alarm_register_next_normal(now_utime, normal_list);
+
+       }
+       if (normal_list)
+       {
+               g_list_free_full(normal_list, free);
+               normal_list = NULL;
+       }
+
+       // for allday
+       DBG("allday");
+       time_t now_timet;
+       time_t from_timet, to_timet;
+       int from_datetime, to_datetime;
+       struct tm datetime_tm;
+       now_timet = time(NULL);
+
+       event_count = 0;
+       todo_count = 0;
+       to_timet = now_timet;
+
+       // searching 3months, next 6months, next 12months
+       for (loop_count = 1; loop_count < 4; loop_count++)
+       {
+               from_timet = to_timet;
+               gmtime_r(&from_timet, &datetime_tm);
+               from_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
+
+               to_timet = from_timet + (60 * 60 * 24 * 30 * 3 * loop_count);
+               gmtime_r(&to_timet, &datetime_tm);
+               to_datetime = (1900 + datetime_tm.tm_year) * 10000 + (datetime_tm.tm_mon + 1) * 100 + datetime_tm.tm_mday;
+
+               __cal_server_alarm_get_next_list_allday_event(from_datetime, to_datetime, &allday_list, &event_count);
+               __cal_server_alarm_get_next_list_allday_todo(from_datetime, to_datetime, &allday_list, &todo_count);
+
+               if (event_count + todo_count > 0)
+               {
+                       break;
+               }
+       }
+       DBG("event count(%d) todo count(%d)", event_count, todo_count);
+
+       if (event_count + todo_count > 0)
+       {
+               allday_list = g_list_sort(allday_list, __cal_server_alarm_allday_sort_cb);
+               DBG("after sorting");
+               g_list_foreach(allday_list, (GFunc)__cal_server_alarm_print_list_allday_todo, NULL);
+               __cal_server_alarm_register_next_allday(now_timet, allday_list);
+       }
+       if (allday_list)
+       {
+               g_list_free_full(allday_list, free);
+               allday_list = NULL;
+       }
+
+       int diff;
+       gettimeofday(&etv, NULL);
+       diff = ((int)etv.tv_sec *1000 + (int)etv.tv_usec/1000)
+               -((int)stv.tv_sec *1000 + (int)stv.tv_usec/1000);
+       DBG("registering time diff %ld(%d.%d)",diff, diff/1000, diff%1000); // time check
+       return 0;
+}
+
+static int _alert_cb(alarm_id_t alarm_id, void *data)
+{
+       GList *normal_list = NULL;
+       GList *allday_list = NULL;
+
+       __cal_server_alarm_get_list_with_alarmmgr_id(alarm_id, &normal_list, &allday_list);
+       __cal_server_alarm_unset_alerted_alarmmgr_id(alarm_id);
+       __cal_server_alarm_noti_with_appsvc(alarm_id, normal_list, allday_list);
+       if (normal_list)
+       {
+               g_list_free_full(normal_list, free);
+               normal_list = NULL;
+       }
+       if (allday_list)
+       {
+               g_list_free_full(allday_list, free);
+               allday_list = NULL;
+       }
+
+       __cal_server_alarm_register_with_alarmmgr();
+       return 0;
+}
+
+////////////////////////////////////////////////////////////////////
+static void __cal_server_alarm_timechange_cb(keynode_t *node, void *data)
+{
+       __cal_server_alarm_register_with_alarmmgr();
+}
+
+int __cal_server_alarm_set_timechange(void)
+{
+       int ret;
+
+       ret = vconf_notify_key_changed(VCONFKEY_SYSTEM_TIMECHANGE,
+                       __cal_server_alarm_timechange_cb, NULL);
+       if (ret < 0)
+       {
+               ERR("vconf_ignore_key_changed() failed");
+               return ret;
+       }
+       return CALENDAR_ERROR_NONE;
+}
+
+static void __changed_cb(const char* view_uri, void* data)
+{
+       __cal_server_alarm_register_with_alarmmgr();
+}
+
+static int __cal_server_alarm_set_inotify(calendar_db_changed_cb callback)
+{
+       _cal_inotify_subscribe(CAL_NOTI_TYPE_EVENT, CAL_NOTI_EVENT_CHANGED, callback, NULL);
+       _cal_inotify_subscribe(CAL_NOTI_TYPE_TODO, CAL_NOTI_TODO_CHANGED, callback, NULL);
+       return 0;
+}
+
+int _cal_server_alarm(void)
+{
+       int ret;
+
+       __cal_server_alarm_set_timechange();
+       __cal_server_alarm_set_inotify(__changed_cb);
+
+       ret = alarmmgr_init("calendar-service");
+       retvm_if(ret < 0, ret, "alarmmgr_init() failed");
+
+       ret = alarmmgr_set_cb(_alert_cb, NULL);
+       retvm_if(ret < 0, ret, "alarmmgr_set_cb() failed");
+
+       __cal_server_alarm_register_with_alarmmgr();
+
+       return CALENDAR_ERROR_NONE;
+}
+
diff --git a/server/cal_server_alarm.h b/server/cal_server_alarm.h
new file mode 100644 (file)
index 0000000..38c5da6
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CAL_SERVER_ALARM_H__
+#define __CAL_SERVER_ALARM_H__
+
+int _cal_server_alarm(void);
+
+#endif  //__CAL_SERVER_ALARM_H__
diff --git a/server/cal_server_calendar_delete.c b/server/cal_server_calendar_delete.c
new file mode 100644 (file)
index 0000000..77f9fc8
--- /dev/null
@@ -0,0 +1,372 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 <glib.h>
+#include <unistd.h> //sleep
+
+#include "calendar2.h"
+#include "cal_typedef.h"
+#include "cal_internal.h"
+#include "cal_server_calendar_delete.h"
+#include "cal_db.h"
+#include "cal_db_util.h"
+
+#define CAL_SERVER_CALENDAR_DELETE_COUNT 50
+#define CAL_SERVER_CALENDAR_DELETE_STEP_TIME 1
+#define CAL_SERVER_CALENDAR_DELETE_THREAD_NAME "cal_server_calendar_delete"
+
+typedef enum
+{
+    STEP_1, // create calendar_id_list
+    STEP_2, // delete schedule_table <-- CAL_SERVER_CALENDAR_DELETE_COUNT
+            // loop STEP_2
+    STEP_3, // delete calendar_table
+} __calendar_delete_step_e;
+
+typedef struct {
+    GList *calendar_id_list;
+    int current_calendar_id;
+    __calendar_delete_step_e step;
+} __calendar_delete_data_s;
+
+GThread *__cal_server_calendar_delete_thread = NULL;
+GCond __cal_server_calendar_delete_cond;
+GMutex __cal_server_calendar_delete_mutex;
+
+static bool __cal_server_calendar_delete_step(int ret, __calendar_delete_data_s* data);
+static int __cal_server_calendar_delete_step1(__calendar_delete_data_s* data);
+static int __cal_server_calendar_delete_step2(__calendar_delete_data_s* data);
+static int __cal_server_calendar_delete_step3(__calendar_delete_data_s* data);
+static bool  __cal_server_calendar_run(__calendar_delete_data_s* data);
+static gpointer  __cal_server_calendar_main(gpointer user_data);
+
+static bool __cal_server_calendar_delete_step(int ret, __calendar_delete_data_s* data)
+{
+    if (ret != CALENDAR_ERROR_NONE && ret != CALENDAR_ERROR_NO_DATA)
+    {
+        if(data->calendar_id_list)
+        {
+            g_list_free(data->calendar_id_list);
+        }
+        CAL_FREE(data);
+        ERR("fail (%d)",ret);
+
+        return false;
+    }
+    switch (data->step)
+    {
+    case STEP_1:
+        if (ret == CALENDAR_ERROR_NO_DATA)
+        {
+            if(data->calendar_id_list)
+            {
+                g_list_free(data->calendar_id_list);
+            }
+            CAL_FREE(data);
+            ERR("step_1 no_data");
+
+            return false;
+        }
+        data->step = STEP_2;
+        break;
+    case STEP_2:
+        if (ret == CALENDAR_ERROR_NO_DATA)
+        {
+            data->step = STEP_3;
+        }
+        break;
+    case STEP_3:
+        data->step = STEP_1;
+        break;
+    default:
+        data->step = STEP_1;
+        break;
+    }
+
+    // go next step
+    return true;
+}
+
+static int __cal_server_calendar_delete_step1(__calendar_delete_data_s* data)
+{
+    char query[CAL_DB_SQL_MIN_LEN] = {0,};
+    sqlite3_stmt *stmt = NULL;
+    int count = 0;
+
+    CAL_FN_CALL;
+
+    if (data->calendar_id_list == NULL)
+    {
+        // get event_list
+        snprintf(query, sizeof(query), "SELECT id FROM %s "
+                "WHERE deleted = 1",
+                CAL_TABLE_CALENDAR);
+
+        stmt = _cal_db_util_query_prepare(query);
+        if (NULL == stmt)
+        {
+            ERR("_cal_db_util_query_prepare() Failed");
+            return CALENDAR_ERROR_DB_FAILED;
+        }
+        while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+        {
+            int id = 0;
+            id = sqlite3_column_int(stmt, 0);
+            data->calendar_id_list = g_list_append(data->calendar_id_list, GINT_TO_POINTER(id));
+        }
+        sqlite3_finalize(stmt);
+    }
+
+    count = g_list_length(data->calendar_id_list);
+    if ( count <= 0)
+    {
+        return CALENDAR_ERROR_NO_DATA;
+    }
+
+    GList *cursor = g_list_first(data->calendar_id_list);
+    if (cursor)
+    {
+        data->current_calendar_id = GPOINTER_TO_INT(cursor->data);
+        data->calendar_id_list = g_list_remove(data->calendar_id_list, GINT_TO_POINTER(data->current_calendar_id));
+
+        return CALENDAR_ERROR_NONE;
+    }
+    else
+    {
+        return CALENDAR_ERROR_NO_DATA;
+    }
+}
+
+static int __cal_server_calendar_delete_step2(__calendar_delete_data_s* data)
+{
+    int ret;
+    char query[CAL_DB_SQL_MIN_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+    GList *list = NULL;
+    sqlite3_stmt *stmt = NULL;
+    int count = 0;
+
+    CAL_FN_CALL;
+
+    // get event_list
+    snprintf(query, sizeof(query), "SELECT id FROM %s "
+            "WHERE calendar_id = %d LIMIT %d",
+            CAL_TABLE_SCHEDULE,
+            data->current_calendar_id, CAL_SERVER_CALENDAR_DELETE_COUNT);
+
+    stmt = _cal_db_util_query_prepare(query);
+    if (NULL == stmt)
+    {
+        ERR("_cal_db_util_query_prepare() Failed");
+        return CALENDAR_ERROR_DB_FAILED;
+    }
+    while(CAL_DB_ROW == _cal_db_util_stmt_step(stmt))
+    {
+        int id = 0;
+        id = sqlite3_column_int(stmt, 0);
+        list = g_list_append(list, GINT_TO_POINTER(id));
+    }
+
+    sqlite3_finalize(stmt);
+    stmt = NULL;
+
+    count = g_list_length(list);
+    if ( count <= 0)
+    {
+        return CALENDAR_ERROR_NO_DATA;
+    }
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+    GList *cursor = g_list_first(list);
+    while(cursor)
+    {
+        int id = GPOINTER_TO_INT(cursor->data);
+        /* delete event table */
+        snprintf(query, sizeof(query), "DELETE FROM %s "
+                "WHERE id = %d",
+                CAL_TABLE_SCHEDULE,
+                id);
+
+        dbret = _cal_db_util_query_exec(query);
+        CAL_DBG("%s",query);
+               if (CAL_DB_OK != dbret)
+        {
+                       ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+            _cal_db_util_end_trans(false);
+            g_list_free(list);
+                       switch (dbret)
+                       {
+                       case CAL_DB_ERROR_NO_SPACE:
+                               return CALENDAR_ERROR_FILE_NO_SPACE;
+                       default:
+                               return CALENDAR_ERROR_DB_FAILED;
+                       }
+        }
+        cursor = g_list_next(cursor);
+    }
+
+    g_list_free(list);
+
+    _cal_db_util_end_trans(true);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static int __cal_server_calendar_delete_step3(__calendar_delete_data_s* data)
+{
+    int ret;
+    char query[CAL_DB_SQL_MIN_LEN] = {0};
+    cal_db_util_error_e dbret = CAL_DB_OK;
+
+    ret = _cal_db_util_begin_trans();
+    retvm_if( CALENDAR_ERROR_NONE != ret,CALENDAR_ERROR_DB_FAILED, "Db failed" );
+
+    CAL_FN_CALL;
+
+    /* delete event table */
+    snprintf(query, sizeof(query), "DELETE FROM %s "
+            "WHERE id = %d",
+            CAL_TABLE_CALENDAR,
+            data->current_calendar_id);
+
+    dbret = _cal_db_util_query_exec(query);
+       if (CAL_DB_OK != dbret)
+    {
+               ERR("_cal_db_util_query_exec() failed (%d)", dbret);
+        _cal_db_util_end_trans(false);
+               switch (dbret)
+               {
+               case CAL_DB_ERROR_NO_SPACE:
+                       return CALENDAR_ERROR_FILE_NO_SPACE;
+               default:
+                       return CALENDAR_ERROR_DB_FAILED;
+               }
+    }
+
+    _cal_db_util_end_trans(true);
+
+    return CALENDAR_ERROR_NONE;
+}
+
+static bool  __cal_server_calendar_run(__calendar_delete_data_s* data)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    CAL_FN_CALL;
+
+    if(data == NULL)
+    {
+        ERR("data is NULL");
+
+        return false;
+    }
+
+    switch (data->step)
+    {
+    case STEP_1:
+        ret = __cal_server_calendar_delete_step1(data);
+        break;
+    case STEP_2:
+        ret = __cal_server_calendar_delete_step2(data);
+        break;
+    case STEP_3:
+        ret = __cal_server_calendar_delete_step3(data);
+        break;
+    default:
+        ERR("invalid step");
+        if(data->calendar_id_list)
+        {
+            g_list_free(data->calendar_id_list);
+        }
+        CAL_FREE(data);
+
+        return false;
+    }
+
+    return __cal_server_calendar_delete_step(ret, data);
+
+}
+
+static gpointer  __cal_server_calendar_main(gpointer user_data)
+{
+    __calendar_delete_data_s *callback_data = NULL;
+    int ret = CALENDAR_ERROR_NONE;
+    CAL_FN_CALL;
+
+    while(1)
+    {
+        callback_data = calloc(1,sizeof(__calendar_delete_data_s));
+
+        if (callback_data != NULL)
+        {
+            callback_data->step = STEP_1;
+
+            // delete
+            while(1)
+            {
+                ret = calendar_connect();
+                if (CALENDAR_ERROR_NONE != ret)
+                {
+                    break;
+                }
+                sleep(CAL_SERVER_CALENDAR_DELETE_STEP_TIME); // sleep 1 sec.
+                if (__cal_server_calendar_run(callback_data) == false)
+                {
+                    callback_data = NULL;
+                    CAL_DBG("end");
+                    break;
+                }
+            }
+            calendar_disconnect();
+            CAL_FREE(callback_data);
+        }
+        else
+        {
+            ERR("calloc fail");
+        }
+
+        g_mutex_lock(&__cal_server_calendar_delete_mutex);
+        CAL_DBG("wait");
+        g_cond_wait(&__cal_server_calendar_delete_cond, &__cal_server_calendar_delete_mutex);
+        g_mutex_unlock(&__cal_server_calendar_delete_mutex);
+    }
+
+    return NULL;
+}
+
+void _cal_server_calendar_delete_start(void)
+{
+    CAL_FN_CALL;
+
+    if (__cal_server_calendar_delete_thread == NULL)
+    {
+        g_mutex_init(&__cal_server_calendar_delete_mutex);
+        g_cond_init(&__cal_server_calendar_delete_cond);
+        __cal_server_calendar_delete_thread = g_thread_new(CAL_SERVER_CALENDAR_DELETE_THREAD_NAME,__cal_server_calendar_main,NULL);
+    }
+
+    // don't use mutex.
+    g_cond_signal(&__cal_server_calendar_delete_cond);
+
+    return ;
+
+}
diff --git a/server/cal_server_calendar_delete.h b/server/cal_server_calendar_delete.h
new file mode 100644 (file)
index 0000000..3d859b0
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CAL_SERVER_CALENDAR_DELETE_H__
+#define __CAL_SERVER_CALENDAR_DELETE_H__
+
+void _cal_server_calendar_delete_start(void);
+
+#endif /*__CAL_SERVER_CALENDAR_DELETE_H__*/
diff --git a/server/cal_server_ipc.c b/server/cal_server_ipc.c
new file mode 100644 (file)
index 0000000..c2545eb
--- /dev/null
@@ -0,0 +1,1953 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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 "calendar_service.h"
+#include "calendar_db.h"
+#include "calendar_query.h"
+#include "calendar_vcalendar.h"
+#include "calendar_reminder.h"
+
+#include "cal_typedef.h"
+#include "cal_db.h"
+#include "cal_db_util.h"
+#include "cal_ipc_marshal.h"
+#include "cal_internal.h"
+#include "cal_server_ipc.h"
+
+void _cal_server_ipc_connect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    ret = calendar_connect();
+
+    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 _cal_server_ipc_disconnect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+
+    ret = calendar_disconnect();
+
+    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;
+}
+
+// calendar_db.h
+void _cal_server_ipc_db_insert_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_record_h record = NULL;
+    int id = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_record(indata,&record);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            record = NULL;
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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 == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                *outdata = NULL;
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto ERROR_RETURN;
+            }
+            if (_cal_ipc_marshal_int(id,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                *outdata = NULL;
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto ERROR_RETURN;
+            }
+/*
+            ret = _cal_ipc_marshal_record_get_primary_id(record, &property_id, &id);
+
+            if (ret == CALENDAR_ERROR_NONE)
+            {
+                if (pims_ipc_data_put(*outdata,(void*)&property_id,sizeof(unsigned int)) != 0)
+                {
+                    pims_ipc_data_destroy(*outdata);
+                    ERR("_cal_ipc_marshal fail");
+                    ret = CALENDAR_ERROR_INVALID_PARAMETER;
+                    goto ERROR_RETURN;
+                }
+                if (_cal_ipc_marshal_int(id,*outdata) != CALENDAR_ERROR_NONE)
+                {
+                    pims_ipc_data_destroy(*outdata);
+                    ERR("_cal_ipc_marshal fail");
+                    ret = CALENDAR_ERROR_INVALID_PARAMETER;
+                    goto ERROR_RETURN;
+                }
+            }
+            else
+            {
+                pims_ipc_data_destroy(*outdata);
+                ret = CALENDAR_ERROR_INVALID_PARAMETER;
+                goto ERROR_RETURN;
+            }
+*/
+        }
+    }
+    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 (record)
+    {
+        calendar_record_destroy(record,true);
+    }
+    return;
+}
+
+void _cal_server_ipc_db_get_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char* view_uri = NULL;
+    int id = 0;
+    calendar_record_h record = NULL;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata,&view_uri);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_char fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&id);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_get_record(view_uri,id,&record);
+
+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 (_cal_ipc_marshal_record(record, *outdata) != CALENDAR_ERROR_NONE)
+        {
+            pims_ipc_data_destroy(*outdata);
+            *outdata = NULL;
+            ERR("_cal_ipc_marshal_record fail");
+            goto DATA_FREE;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+DATA_FREE:
+    if (record)
+    {
+        calendar_record_destroy(record,true);
+    }
+    CAL_FREE(view_uri);
+    return;
+}
+
+void _cal_server_ipc_db_update_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_record_h record = NULL;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_record(indata,&record);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_update_record(record);
+
+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 (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto DATA_FREE;
+            }
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+DATA_FREE:
+    if (record)
+    {
+        calendar_record_destroy(record,true);
+    }
+    return;
+}
+
+void _cal_server_ipc_db_delete_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char* view_uri = NULL;
+    int id = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata,&view_uri);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&id);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_delete_record(view_uri,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;
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto DATA_FREE;
+            }
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+DATA_FREE:
+
+    CAL_FREE(view_uri);
+    return;
+}
+
+void _cal_server_ipc_db_get_all_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char* view_uri = NULL;
+    int offset = 0;
+    int limit = 0;
+    calendar_list_h list = NULL;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata,&view_uri);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&offset);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&limit);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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;
+        }
+        ret = _cal_ipc_marshal_list(list,*outdata);
+
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    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)
+    {
+        calendar_list_destroy(list,true);
+    }
+    CAL_FREE(view_uri);
+    return;
+}
+
+void _cal_server_ipc_db_get_records_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_query_h query = NULL;
+    int offset = 0;
+    int limit = 0;
+    calendar_list_h list = NULL;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_query(indata,&query);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&offset);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&limit);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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;
+        }
+        ret = _cal_ipc_marshal_list(list,*outdata);
+
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    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)
+    {
+        calendar_list_destroy(list,true);
+    }
+    if (query)
+    {
+        calendar_query_destroy(query);
+    }
+    return;
+}
+
+void _cal_server_ipc_db_clean_after_sync(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    int calendar_book_id = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_int(indata,&calendar_book_id);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_clean_after_sync(calendar_book_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;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+
+    return;
+}
+
+void _cal_server_ipc_db_get_count(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char* view_uri = NULL;
+    int count = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata,&view_uri);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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;
+        }
+        ret = _cal_ipc_marshal_int(count,*outdata);
+
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    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:
+    CAL_FREE(view_uri);
+    return;
+}
+
+void _cal_server_ipc_db_get_count_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_query_h query = NULL;
+    int count = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_query(indata,&query);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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;
+        }
+        ret = _cal_ipc_marshal_int(count,*outdata);
+
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    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 (query)
+    {
+        calendar_query_destroy(query);
+    }
+    return;
+}
+
+void _cal_server_ipc_db_insert_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_list_h list = NULL;
+    int id_count = 0;
+    int *ids = NULL;
+    int i=0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_list(indata,&list);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_list fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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 == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto ERROR_RETURN;
+            }
+            // marshal : id_count+[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 = CALENDAR_ERROR_INVALID_PARAMETER;
+                goto ERROR_RETURN;
+            }
+
+            for(i=0;i<id_count;i++)
+            {
+                // marshal ids
+                if (pims_ipc_data_put(*outdata,(void*)&ids[i],sizeof(int)) != 0)
+                {
+                    pims_ipc_data_destroy(*outdata);
+                    *outdata = NULL;
+                    ERR("pims_ipc_data_put fail");
+                    ret = CALENDAR_ERROR_INVALID_PARAMETER;
+                    goto ERROR_RETURN;
+                }
+            }
+        }
+    }
+    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)
+    {
+        calendar_list_destroy(list,true);
+    }
+    CAL_FREE(ids);
+    return;
+}
+
+void _cal_server_ipc_db_update_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    calendar_list_h list = NULL;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_list(indata,&list);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_list fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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;
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                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)
+    {
+        calendar_list_destroy(list,true);
+    }
+    return;
+}
+
+void _cal_server_ipc_db_delete_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    int count = 0;
+    int *ids = NULL;
+    char *uri = NULL;
+    int i = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata,&uri);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_char fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&count);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+        if (count <=0)
+        {
+            goto ERROR_RETURN;
+        }
+        ids = (int*)malloc(sizeof(int)*count);
+        for(i=0;i<count;i++)
+        {
+            ret = _cal_ipc_unmarshal_int(indata,&ids[i]);
+            if (ret != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_unmarshal_int fail");
+                goto ERROR_RETURN;
+            }
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_delete_records(uri,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;
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                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:
+    CAL_FREE(uri);
+    CAL_FREE(ids);
+    return;
+}
+
+void _cal_server_ipc_db_get_changes_by_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char* view_uri = NULL;
+    int calendar_book_id = 0;
+    int calendar_db_version = 0;
+    calendar_list_h record_list = NULL;
+    int current_calendar_db_version = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata,&view_uri);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_char fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&calendar_book_id);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&calendar_db_version);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_get_changes_by_version(view_uri,calendar_book_id,calendar_db_version,&record_list,&current_calendar_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;
+        }
+        ret = _cal_ipc_marshal_list(record_list,*outdata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal_list fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_marshal_int(current_calendar_db_version,*outdata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+    }
+    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 (record_list)
+    {
+        calendar_list_destroy(record_list,true);
+    }
+    CAL_FREE(view_uri);
+    return;
+}
+
+void _cal_server_ipc_db_get_current_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    int calendar_db_version = 0;
+
+    ret = calendar_db_get_current_version(&calendar_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;
+        }
+        ret = _cal_ipc_marshal_int(calendar_db_version,*outdata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_marshal_int fail");
+            return;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+    return;
+}
+
+void _cal_server_ipc_db_insert_vcalendars(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char *stream = NULL;
+    int count = 0;
+    int *ids = NULL;
+    int i = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata, &stream);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("db_insert_vcalendars fail.");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_insert_vcalendars(stream, &ids, &count);
+
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_db_insert_vcalendars fail");
+        goto ERROR_RETURN;
+    }
+
+    if (outdata)
+    {
+        *outdata = pims_ipc_data_create(0);
+        if (!*outdata)
+        {
+            ERR("pims_ipc_data_create fail");
+            goto DATA_FREE;
+        }
+        // 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");
+            goto DATA_FREE;
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                *outdata = NULL;
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto ERROR_RETURN;
+            }
+        }
+        // count
+        ret = _cal_ipc_marshal_int(count,*outdata);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            pims_ipc_data_destroy(*outdata);
+            *outdata = NULL;
+            ERR("_cal_ipc_marshal_list fail");
+            goto ERROR_RETURN;
+        }
+        for(i=0;i<count;i++)
+        {
+            ret = _cal_ipc_marshal_int(ids[i],*outdata);
+            if (ret != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                *outdata = NULL;
+                ERR("_cal_ipc_marshal_list fail");
+                goto ERROR_RETURN;
+            }
+        }
+    }
+    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:
+    CAL_FREE(stream);
+    CAL_FREE(ids);
+    return;
+}
+
+void _cal_server_ipc_db_replace_vcalendars(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+    char *stream = NULL;
+    int count = 0;
+    int *ids = NULL;
+    int i = 0;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata, &stream);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata, &count);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+        ids = (int*)malloc(sizeof(int)*count);
+        if (ids == NULL)
+        {
+            ERR("malloc fail");
+            goto ERROR_RETURN;
+        }
+        for(i=0;i<count;i++)
+        {
+            ret = _cal_ipc_unmarshal_int(indata, &ids[i]);
+            if (ret != CALENDAR_ERROR_NONE)
+            {
+                ERR("unmarshal fail");
+                goto ERROR_RETURN;
+            }
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("db_replace_vcalendars fail.");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_db_replace_vcalendars(stream, ids, count);
+
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_db_insert_vcalendars fail");
+        goto ERROR_RETURN;
+    }
+
+    if (outdata)
+    {
+        *outdata = pims_ipc_data_create(0);
+        if (!*outdata)
+        {
+            ERR("pims_ipc_data_create fail");
+            goto DATA_FREE;
+        }
+        // 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");
+            goto DATA_FREE;
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                *outdata = NULL;
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                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:
+    CAL_FREE(stream);
+    CAL_FREE(ids);
+    return;
+}
+
+void _cal_server_ipc_db_replace_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       int id = 0;
+    calendar_record_h record = NULL;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_record(indata,&record);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata,&id);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_record fail");
+            goto ERROR_RETURN;
+        }
+    }
+
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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;
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                *outdata = NULL;
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                goto DATA_FREE;
+            }
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+DATA_FREE:
+    if (record)
+    {
+        calendar_record_destroy(record,true);
+    }
+    return;
+}
+
+void _cal_server_ipc_db_replace_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       int i;
+    int count = 0;
+    int *ids = NULL;
+    calendar_list_h list = NULL;
+
+    if (indata)
+    {
+        ret = _cal_ipc_unmarshal_list(indata,&list);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_list fail");
+            goto ERROR_RETURN;
+        }
+        ret = _cal_ipc_unmarshal_int(indata, &count);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("_cal_ipc_unmarshal_int fail");
+            goto ERROR_RETURN;
+        }
+        if (count <= 0)
+        {
+            goto ERROR_RETURN;
+        }
+        ids = (int*)malloc(sizeof(int) * count);
+        for(i = 0; i < count; i++)
+        {
+            ret = _cal_ipc_unmarshal_int(indata,&ids[i]);
+            if (ret != CALENDAR_ERROR_NONE)
+            {
+                ERR("_cal_ipc_unmarshal_int fail");
+                goto ERROR_RETURN;
+            }
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("_cal_server_ipc_db_insert_record fail");
+        goto ERROR_RETURN;
+    }
+
+    ret = calendar_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;
+        }
+        if (ret == CALENDAR_ERROR_NONE)
+        {
+            int transaction_ver = _cal_db_util_get_transaction_ver();
+            if (_cal_ipc_marshal_int(transaction_ver,*outdata) != CALENDAR_ERROR_NONE)
+            {
+                pims_ipc_data_destroy(*outdata);
+                *outdata = NULL;
+                ERR("_cal_ipc_marshal fail");
+                ret = CALENDAR_ERROR_OUT_OF_MEMORY;
+                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:
+    CAL_FREE(ids);
+    if (list)
+    {
+        calendar_list_destroy(list,true);
+    }
+    return;
+}
+
+void _cal_server_ipc_db_register_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       char *pkgname;
+       char *extra_data_key;
+       char *extra_data_value;
+
+       if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata, &pkgname);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+               ret = _cal_ipc_unmarshal_char(indata, &extra_data_key);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+               ret = _cal_ipc_unmarshal_char(indata, &extra_data_value);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("db_insert_vcalendars fail.");
+        goto ERROR_RETURN;
+    }
+
+       ret = calendar_reminder_add_receiver(pkgname, extra_data_key, extra_data_value);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_reminder_add_receiver() fail");
+        goto ERROR_RETURN;
+    }
+
+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;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+    return;
+}
+
+void _cal_server_ipc_db_unregister_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       char *pkgname;
+
+       if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata, &pkgname);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("db_insert_vcalendars fail.");
+        goto ERROR_RETURN;
+    }
+
+       ret = calendar_reminder_remove_receiver(pkgname);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_reminder_remove_receiver() fail");
+        goto ERROR_RETURN;
+    }
+
+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;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+    return;
+}
+
+void _cal_server_ipc_db_activate_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       char *pkgname;
+
+       if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata, &pkgname);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("db_insert_vcalendars fail.");
+        goto ERROR_RETURN;
+    }
+
+       ret = calendar_reminder_activate_receiver(pkgname);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_reminder_activate_receiver() fail");
+        goto ERROR_RETURN;
+    }
+
+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;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+    return;
+}
+
+void _cal_server_ipc_db_deactivate_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       char *pkgname;
+
+       if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata, &pkgname);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("db_insert_vcalendars fail.");
+        goto ERROR_RETURN;
+    }
+
+       ret = calendar_reminder_deactivate_receiver(pkgname);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_reminder_deactivate_pkgname() fail");
+        goto ERROR_RETURN;
+    }
+
+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;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+    return;
+}
+
+void _cal_server_ipc_db_has_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata)
+{
+    int ret = CALENDAR_ERROR_NONE;
+       char *pkgname;
+
+       if (indata)
+    {
+        ret = _cal_ipc_unmarshal_char(indata, &pkgname);
+        if (ret != CALENDAR_ERROR_NONE)
+        {
+            ERR("unmarshal fail");
+            goto ERROR_RETURN;
+        }
+    }
+    else
+    {
+        ret = CALENDAR_ERROR_INVALID_PARAMETER;
+        ERR("db_insert_vcalendars fail.");
+        goto ERROR_RETURN;
+    }
+
+       ret = calendar_reminder_has_receiver(pkgname);
+    if (ret != CALENDAR_ERROR_NONE)
+    {
+        ERR("calendar_reminder_deactivate_pkgname() fail");
+        goto ERROR_RETURN;
+    }
+
+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;
+        }
+    }
+    else
+    {
+        ERR("outdata is NULL");
+    }
+    return;
+}
+
diff --git a/server/cal_server_ipc.h b/server/cal_server_ipc.h
new file mode 100644 (file)
index 0000000..f0ed5a3
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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 __CAL_SERVER_IPC_H__
+#define __CAL_SERVER_IPC_H__
+
+#include <pims-ipc-data.h>
+
+// calendar_service.h
+void _cal_server_ipc_connect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_disconnect(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+// calendar_db.h
+void _cal_server_ipc_db_insert_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_get_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_update_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_delete_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_get_all_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_get_records_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_clean_after_sync(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_get_count(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_get_count_with_query(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_insert_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_update_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_delete_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_get_changes_by_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_get_current_version(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_insert_vcalendars(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_replace_vcalendars(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_replace_record(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_replace_records(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_register_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_unregister_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_activate_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_deactivate_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+void _cal_server_ipc_db_has_reminder(pims_ipc_h ipc, pims_ipc_data_h indata, pims_ipc_data_h *outdata, void *userdata);
+
+
+#endif /*__CAL_SERVER_IPC_H__*/
diff --git a/server/calendar-serviced.sh b/server/calendar-serviced.sh
new file mode 100755 (executable)
index 0000000..4157464
--- /dev/null
@@ -0,0 +1,3 @@
+#dlogutil -v threadtime -f /var/log/calendar-serviced.log -r 1000 -n 10 CALENDAR_SVC &
+
+/usr/bin/calendar-serviced &