Add aggregation APIs 71/125871/13 accepted/tizen/unified/20170512.165334 submit/tizen/20170512.044025
authorJeesun Kim <iamjs.kim@samsung.com>
Wed, 19 Apr 2017 07:16:53 +0000 (16:16 +0900)
committerJeesun Kim <iamjs.kim@samsung.com>
Fri, 12 May 2017 04:37:28 +0000 (13:37 +0900)
Change-Id: Ib5f8e25cde54f3ca5826c86f3941b090f7dec6a1

23 files changed:
build-util/schema.sql
client/cal_client_db.c
client/cal_client_dbus.c
client/cal_client_dbus.h
common/cal_record_event.c
common/cal_typedef.h
common/cal_view.c
common/cal_view.h
common/dbus/cal_dbus.xml
include/calendar_db.h
include/calendar_view.h
packaging/calendar-service.conf.in
server/cal_server_alarm.c
server/cal_server_dbus.c
server/cal_server_schema.c
server/cal_server_update.c
server/db/cal_db.h
server/db/cal_db_link.c [new file with mode: 0644]
server/db/cal_db_link.h [new file with mode: 0644]
server/db/cal_db_plugin_event.c
server/db/cal_db_plugin_event.h [new file with mode: 0644]
server/db/cal_db_plugin_instance_localtime.c
server/db/cal_db_plugin_todo.c

index 33a5d52..e9d564c 100644 (file)
@@ -15,7 +15,7 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 --
-PRAGMA user_version = 107;
+PRAGMA user_version = 108;
 PRAGMA journal_mode = WAL;
 
 CREATE TABLE schedule_table
@@ -71,7 +71,9 @@ sync_data4 TEXT,
 has_exception INTEGER DEFAULT 0,
 has_extended INTEGER DEFAULT 0,
 freq INTEGER DEFAULT 0,
-is_allday INTEGER DEFAULT 0
+is_allday INTEGER DEFAULT 0,
+link_count INTEGER DEFAULT 0,
+link_base_id INTEGER DEFAULT 0
 );
 CREATE INDEX sch_idx1 ON schedule_table(type);
 CREATE INDEX sch_idx2 ON schedule_table(calendar_id);
@@ -84,6 +86,19 @@ CREATE TRIGGER trg_original_mod AFTER UPDATE OF is_deleted ON schedule_table
    UPDATE schedule_table SET is_deleted = 1 WHERE original_event_id = old.id;
  END;
 
+CREATE TRIGGER trg_link_mod AFTER UPDATE OF link_count ON schedule_table
+ BEGIN
+       UPDATE schedule_table SET link_count = link_count + (SELECT link_count FROM schedule_table WHERE link_base_id = new.id) WHERE id = new.id; -- base is linked to new base
+       UPDATE schedule_table SET link_base_id = new.id WHERE link_base_id = (SELECT id FROM schedule_table WHERE link_base_id = new.id); -- new is linked to base
+       UPDATE schedule_table SET link_count = 0 WHERE link_base_id = new.id; -- set count 0
+ END;
+
+CREATE TRIGGER trg_link_del BEFORE DELETE ON schedule_table
+ BEGIN
+       UPDATE schedule_table SET link_base_id = 0 WHERE link_base_id = old.id; -- when base record is deleted.
+       UPDATE schedule_table SET link_count = link_count -1 WHERE id = old.link_base_id; -- when linked record is deleted.
+ END;
+
 CREATE TRIGGER trg_schedule_del AFTER DELETE ON schedule_table
  BEGIN
    DELETE FROM rrule_table WHERE event_id = old.id;
index 1d429b1..860c628 100644 (file)
@@ -385,3 +385,37 @@ EXPORT_API int calendar_db_get_changes_exception_by_version(const char* view_uri
        return ret;
 }
 
+/*
+ * when record is linked or unlinked
+ * we should consider how to handle alarm, attendee, exception, extended.
+ * ONLY supported in event view.
+ */
+EXPORT_API int calendar_db_link_record(int base_id, int record_id)
+{
+       CAL_FN_CALL();
+
+       RETV_IF(base_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER);
+       RETV_IF(record_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       int ret = 0;
+       calendar_h handle = NULL;
+       ret = cal_client_handle_get_p(&handle);
+       RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_client_handle_get_p() Fail(%d)", ret);
+       CAL_DBUS_RETRY_CALL(ret, cal_dbus_link_record(handle, base_id, record_id));
+       return ret;
+}
+
+EXPORT_API int calendar_db_unlink_record(int record_id)
+{
+       CAL_FN_CALL();
+
+       RETV_IF(record_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       int ret = 0;
+       calendar_h handle = NULL;
+       ret = cal_client_handle_get_p(&handle);
+       RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_client_handle_get_p() Fail(%d)", ret);
+       CAL_DBUS_RETRY_CALL(ret, cal_dbus_unlink_record(handle, record_id));
+       return ret;
+}
+
index 1bc02cc..4022964 100644 (file)
@@ -1022,3 +1022,54 @@ int cal_dbus_replace_vcalendars(calendar_h handle, const char *stream,
        return ret;
 }
 
+int cal_dbus_link_record(calendar_h handle, int base_id, int record_id)
+{
+       RETV_IF(NULL == handle, CALENDAR_ERROR_INVALID_PARAMETER);
+       RETV_IF(base_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER);
+       RETV_IF(record_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       int ret = 0;
+       GError *error = NULL;
+       GVariant *arg_handle = cal_dbus_utils_handle_to_gvariant(handle);
+       cal_dbus_call_link_record_sync(cal_dbus_object, arg_handle, base_id, record_id,
+                       &ret, NULL, &error);
+       if (error) {
+               /* LCOV_EXCL_START */
+               ERR("cal_dbus_call_link_record() Fail[%s]",  error->message);
+               if (G_DBUS_ERROR_ACCESS_DENIED == error->code)
+                       ret = CALENDAR_ERROR_PERMISSION_DENIED;
+               else
+                       ret = CALENDAR_ERROR_IPC;
+               g_error_free(error);
+               g_variant_unref(arg_handle);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+       return ret;
+}
+
+int cal_dbus_unlink_record(calendar_h handle, int record_id)
+{
+       RETV_IF(NULL == handle, CALENDAR_ERROR_INVALID_PARAMETER);
+       RETV_IF(record_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER);
+
+       int ret = 0;
+       GError *error = NULL;
+       GVariant *arg_handle = cal_dbus_utils_handle_to_gvariant(handle);
+       cal_dbus_call_unlink_record_sync(cal_dbus_object, arg_handle, record_id,
+                       &ret, NULL, &error);
+       if (error) {
+               /* LCOV_EXCL_START */
+               ERR("cal_dbus_call_unlink_record() Fail[%s]",  error->message);
+               if (G_DBUS_ERROR_ACCESS_DENIED == error->code)
+                       ret = CALENDAR_ERROR_PERMISSION_DENIED;
+               else
+                       ret = CALENDAR_ERROR_IPC;
+               g_error_free(error);
+               g_variant_unref(arg_handle);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+       return ret;
+}
+
index 93b6a77..3e6c269 100644 (file)
@@ -72,5 +72,7 @@ int cal_dbus_insert_vcalendars(calendar_h handle, const char *stream, int **out_
 int cal_dbus_replace_vcalendars(calendar_h handle, const char *stream, int *ids,
                int count);
 int cal_dbus_recovery(void);
+int cal_dbus_link_record(calendar_h handle, int base_id, int record_id);
+int cal_dbus_unlink_record(calendar_h handle, int record_id);
 
 #endif /* __CAL_CLIENT_DBUS_H__ */
index e1f3a22..00c0682 100644 (file)
@@ -501,6 +501,12 @@ static int _cal_record_event_get_int(calendar_record_h record, unsigned int prop
        case CAL_PROPERTY_EVENT_IS_ALLDAY:
                *out_value = (rec->is_allday);
                break;
+       case CAL_PROPERTY_EVENT_LINK_COUNT:
+               *out_value = (rec->link_count);
+               break;
+       case CAL_PROPERTY_EVENT_LINK_BASE_ID:
+               *out_value = (rec->link_base_id);
+               break;
        default:
                return CALENDAR_ERROR_INVALID_PARAMETER;
        }
index 8b644ee..4f4af77 100644 (file)
@@ -145,6 +145,8 @@ typedef struct {
        cal_list_s *attendee_list;
        cal_list_s *exception_list;
        cal_list_s *extended_list;
+       int link_count;
+       int link_base_id;
 } cal_event_s;
 
 typedef struct {
index c67cef3..aa7d91e 100644 (file)
@@ -102,7 +102,9 @@ EXPORT_API const _calendar_event_property_ids   _calendar_event = {
        .calendar_attendee = CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE,
        .exception = CAL_PROPERTY_EVENT_EXCEPTION,
        .extended = CAL_PROPERTY_EVENT_EXTENDED,
-       .is_allday = CAL_PROPERTY_EVENT_IS_ALLDAY
+       .is_allday = CAL_PROPERTY_EVENT_IS_ALLDAY,
+       .link_count = CAL_PROPERTY_EVENT_LINK_COUNT,
+       .link_base_id = CAL_PROPERTY_EVENT_LINK_BASE_ID,
 };
 
 EXPORT_API const _calendar_todo_property_ids   _calendar_todo = {
@@ -578,6 +580,8 @@ const cal_property_info_s   __property_event[] = {
        {CAL_PROPERTY_EVENT_EXCEPTION,              NULL},
        {CAL_PROPERTY_EVENT_EXTENDED,               NULL},
        {CAL_PROPERTY_EVENT_IS_ALLDAY,              "is_allday"},
+       {CAL_PROPERTY_EVENT_LINK_COUNT,            "link_count"},
+       {CAL_PROPERTY_EVENT_LINK_BASE_ID,          "link_base_id"},
 };
 
 const cal_property_info_s   __property_todo[] = {
index 34e0b51..ffa3106 100644 (file)
@@ -156,6 +156,8 @@ typedef enum {
        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_EVENT_LINK_COUNT           = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) + 57,
+       CAL_PROPERTY_EVENT_LINK_BASE_ID         = (CAL_PROPERTY_EVENT|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY) + 58,
 
        CAL_PROPERTY_TODO_ID                    = (CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT|CAL_PROPERTY_FLAGS_READ_ONLY),
        CAL_PROPERTY_TODO_BOOK_ID               = (CAL_PROPERTY_TODO|CAL_PROPERTY_DATA_TYPE_INT) + 1,
index b83a7ad..63b36cf 100644 (file)
                        <arg type="i" name="ret" direction="out"/>
                        <arg type="i" name="version" direction="out"/>
                </method>
+               <method name="link_record">
+                       <arg type="(ii)" name="handle" direction="in"/>
+                       <arg type="i" name="base_id" direction="in"/>
+                       <arg type="i" name="record_id" direction="in"/>
+                       <arg type="i" name="ret" direction="out"/>
+               </method>
+               <method name="unlink_record">
+                       <arg type="(ii)" name="handle" direction="in"/>
+                       <arg type="i" name="record_id" direction="in"/>
+                       <arg type="i" name="ret" direction="out"/>
+               </method>
        </interface>
 </node>
 
index c9d984f..d5d847e 100644 (file)
@@ -604,6 +604,46 @@ int calendar_db_get_changes_exception_by_version(const char* view_uri, int origi
  */
 int calendar_db_clean_after_sync(int calendar_book_id, int calendar_db_version);
 
+/**
+ * @brief Links a record to another record.
+ * @since_tizen 4.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/calendar.write
+ * @param[in] base_id The base record ID
+ * @param[in] record_id The record ID to link to
+ * @return @c 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
+ * @retval #CALENDAR_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #CALENDAR_ERROR_FILE_NO_SPACE File system is full
+ * @retval #CALENDAR_ERROR_IPC Unknown IPC error
+ * @pre calendar_connect() should be called to open a connection to the calendar service.
+ * @see calendar_connect()
+ */
+int calendar_db_link_record(int base_id, int record_id);
+
+/**
+ * @brief Unlinks a record from base record.
+ * @since_tizen 4.0
+ * @privlevel public
+ * @privilege %http://tizen.org/privilege/calendar.write
+ * @param[in] record_id The record ID to unlink
+ * @return @c 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
+ * @retval #CALENDAR_ERROR_PERMISSION_DENIED Permission denied
+ * @retval #CALENDAR_ERROR_FILE_NO_SPACE File system is full
+ * @retval #CALENDAR_ERROR_IPC Unknown IPC error
+ * @pre calendar_connect() should be called to open a connection to the calendar service.
+ * @see calendar_connect()
+ */
+int calendar_db_unlink_record(int record_id);
 
 /**
  * @}
index 9f0e35d..3191222 100644 (file)
@@ -144,6 +144,8 @@ _CALENDAR_END_VIEW(_calendar_book)
  *     <tr><td> child list </td><td> exception </td><td> read, write </td><td>The exception mod event list of the event</td></tr>
  *     <tr><td> child list </td><td> extended </td><td> read, write </td><td>The extended property list of the event. Refer to the @ref CAPI_SOCIAL_CALENDAR_SVC_VIEW_MODULE_calendar_extended_property</td></tr>
  *     <tr><td> interger </td><td> is_allday </td><td> read only </td><td>The event is an allday event or not </td></tr>
+ *     <tr><td> interger </td><td> link_count </td><td> read only </td><td>The event is a linked event (Since 4.0)</td></tr>
+ *     <tr><td> interger </td><td> link_base_id </td><td> read only </td><td>The event is a base linked event (Since 4.0)</td></tr>
  * </table>
  */
 _CALENDAR_BEGIN_VIEW()
@@ -204,6 +206,8 @@ _CALENDAR_BEGIN_VIEW()
        _CALENDAR_PROPERTY_CHILD_MULTIPLE(exception)
        _CALENDAR_PROPERTY_CHILD_MULTIPLE(extended)
        _CALENDAR_PROPERTY_INT(is_allday) /* read only */
+       _CALENDAR_PROPERTY_INT(link_count) /* read only */
+       _CALENDAR_PROPERTY_INT(link_base_id) /* read only */
 _CALENDAR_END_VIEW(_calendar_event)
 
 
index a7e7bd2..ab1e9b7 100644 (file)
                <check send_destination="@DBUS_INTERFACE@"
                                send_interface="@DBUS_INTERFACE@" send_member="replace_vcalendars"
                                privilege="http://tizen.org/privilege/calendar.write"/>
+               <check send_destination="@DBUS_INTERFACE@"
+                               send_interface="@DBUS_INTERFACE@" send_member="link_record"
+                               privilege="http://tizen.org/privilege/calendar.write"/>
+               <check send_destination="@DBUS_INTERFACE@"
+                               send_interface="@DBUS_INTERFACE@" send_member="unlink_record"
+                               privilege="http://tizen.org/privilege/calendar.write"/>
     </policy>
 </busconfig>
 
index d822e6f..c5c4b08 100644 (file)
@@ -417,10 +417,12 @@ static void _cal_server_alarm_get_upcoming_specific_utime(time_t utime, bool get
 {
        int ret = 0;
        char query[CAL_DB_SQL_MAX_LEN] = {0};
-       snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
-                       "alarm_type,alarm_utime,alarm_datetime "
-                       "FROM %s WHERE remind_tick_unit =%d AND alarm_type =%d AND alarm_utime %s %ld %s",
-                       CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
+                       "A.alarm_type, A.alarm_utime, A.alarm_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit = %d AND A.alarm_type = %d "
+                       "AND A.alarm_utime %s %ld %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_UTIME,
                        true == get_all ? "=" : ">", utime,
                        true == get_all ? "" : "ORDER BY alarm_utime ASC LIMIT 1");
 
@@ -463,10 +465,12 @@ static void _cal_server_alarm_get_upcoming_specific_localtime(const char *dateti
 {
        int ret = 0;
        char query[CAL_DB_SQL_MAX_LEN] = {0};
-       snprintf(query, sizeof(query), "SELECT event_id,remind_tick_unit,remind_tick,"
-                       "alarm_type,alarm_utime,alarm_datetime "
-                       "FROM %s WHERE remind_tick_unit=%d AND alarm_type=%d AND alarm_datetime %s '%s' %s",
-                       CAL_TABLE_ALARM, CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
+                       "A.alarm_type, A.alarm_utime, A.alarm_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit = %d AND A.alarm_type = %d "
+                       "AND A.alarm_datetime %s '%s' %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_TIME_LOCALTIME,
                        true == get_all ? "=" : ">", datetime,
                        true == get_all ? "" : "ORDER BY alarm_datetime ASC LIMIT 1");
 
@@ -527,9 +531,11 @@ static void _cal_server_alarm_get_upcoming_nonspecific_event_utime(time_t utime,
        char query[CAL_DB_SQL_MAX_LEN] = {0};
        snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
                        "A.alarm_type,B.dtstart_utime,A.alarm_datetime "
-                       "FROM %s as A, %s as B ON A.event_id = B.event_id "
-                       "WHERE A.remind_tick_unit >%d AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
-                       CAL_TABLE_ALARM, CAL_TABLE_UTIME_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_UTIME_INSTANCE" as B, "CAL_TABLE_SCHEDULE" as S "
+                       "ON A.event_id = B.event_id AND B.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit > %d "
+                       "AND (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
                        true == get_all ? "=" : ">", utime,
                        true == get_all ? "" : "ORDER BY (B.dtstart_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1");
 
@@ -577,12 +583,13 @@ static void _cal_server_alarm_get_upcoming_nonspecific_event_localtime(const cha
         * B:localtime
         */
        char query[CAL_DB_SQL_MAX_LEN] = {0};
-       snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick, "
-                       "A.alarm_type,A.alarm_utime,B.dtstart_datetime "
-                       "FROM %s as A, %s as B ON A.event_id = B.event_id "
-                       "WHERE A.remind_tick_unit >%d AND "
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick, "
+                       "A.alarm_type, A.alarm_utime, B.dtstart_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_LOCALTIME_INSTANCE" as B, "CAL_TABLE_SCHEDULE" as S "
+                       "ON A.event_id = B.event_id AND B.event_id = S.id "
+                       "WHERE S.link_base_id = 0 AND A.remind_tick_unit >%d AND "
                        "(strftime('%%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
-                       CAL_TABLE_ALARM, CAL_TABLE_LOCALTIME_INSTANCE, CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
+                       CALENDAR_ALARM_TIME_UNIT_SPECIFIC,
                        datetime, true == get_all ? "=" : ">",
                        true == get_all ? "" : "ORDER BY (strftime('%s', B.dtstart_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
        sqlite3_stmt *stmt = NULL;
@@ -637,18 +644,17 @@ static void _cal_server_alarm_get_upcoming_nonspecific_todo_utime(time_t utime,
        int ret = 0;
        /*
         * A:alarm
-        * B:todo(utime)
+        * S:todo(utime)
         */
        char query[CAL_DB_SQL_MAX_LEN] = {0};
-       snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
-                       "A.alarm_type,B.dtend_utime,A.alarm_datetime "
-                       "FROM %s as A, %s as B ON A.event_id = B.id "
-                       "WHERE A.remind_tick_unit >%d AND B.type =%d "
-                       "AND (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
+       snprintf(query, sizeof(query), "SELECT A.event_id, A.remind_tick_unit, A.remind_tick,"
+                       "A.alarm_type, S.dtend_utime, A.alarm_datetime "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as S ON A.event_id = S.id "
+                       "WHERE A.remind_tick_unit > %d AND S.type = %d "
+                       "AND (S.dtend_utime - (A.remind_tick_unit * A.remind_tick)) %s %ld %s",
                        CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
                        true == get_all ? "=" : ">", utime,
-                       true == get_all ? "" : "ORDER BY (B.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
+                       true == get_all ? "" : "ORDER BY (S.dtend_utime - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
 
        sqlite3_stmt *stmt = NULL;
        ret = cal_db_util_query_prepare(query, &stmt);
@@ -696,10 +702,9 @@ static void _cal_server_alarm_get_upcoming_nonspecific_todo_localtime(const char
        char query[CAL_DB_SQL_MAX_LEN] = {0};
        snprintf(query, sizeof(query), "SELECT A.event_id,A.remind_tick_unit,A.remind_tick,"
                        "A.alarm_type,A.alarm_utime,B.dtend_datetime "
-                       "FROM %s as A, %s as B ON A.event_id = B.id "
+                       "FROM "CAL_TABLE_ALARM" as A, "CAL_TABLE_SCHEDULE" as B ON A.event_id = B.id "
                        "WHERE A.remind_tick_unit >%d AND B.type =%d "
                        "AND (strftime('%%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick) - strftime('%%s', '%s') %s 0) %s",
-                       CAL_TABLE_ALARM, CAL_TABLE_SCHEDULE,
                        CALENDAR_ALARM_TIME_UNIT_SPECIFIC, CALENDAR_BOOK_TYPE_TODO,
                        datetime, true == get_all ? "=" : ">",
                        true == get_all ? "" : "ORDER BY (strftime('%s', B.dtend_datetime) - (A.remind_tick_unit * A.remind_tick)) LIMIT 1 ");
index 720f64e..01ad2b3 100644 (file)
@@ -520,6 +520,28 @@ static int _cal_server_dbus_find_sender(const char *owner_name, cal_sender_s **o
        return CALENDAR_ERROR_NONE;
 }
 
+static gboolean _handle_link_record(calDbus *object, GDBusMethodInvocation *invocation,
+               GVariant *arg_handle, int base_id, int record_id)
+{
+       int ret = 0;
+       ret = cal_db_link_record(base_id, record_id);
+       cal_dbus_complete_link_record(object, invocation, ret);
+
+       cal_server_ondemand_start();
+       return TRUE;
+}
+
+static gboolean _handle_unlink_record(calDbus *object, GDBusMethodInvocation *invocation,
+               GVariant *arg_handle, int record_id)
+{
+       int ret = 0;
+       ret = cal_db_unlink_record(record_id);
+       cal_dbus_complete_unlink_record(object, invocation, ret);
+
+       cal_server_ondemand_start();
+       return TRUE;
+}
+
 static void _delete_sender(cal_sender_s *sender)
 {
        RET_IF(NULL == sender);
@@ -661,6 +683,10 @@ static void _dbus_on_bus_acquired(GDBusConnection *conn, const gchar *name, gpoi
                        G_CALLBACK(_handle_insert_vcalendars), NULL);
        g_signal_connect(dbus_object, "handle-replace-vcalendars",
                        G_CALLBACK(_handle_replace_vcalendars), NULL);
+       g_signal_connect(dbus_object, "handle-link-record",
+                       G_CALLBACK(_handle_link_record), NULL);
+       g_signal_connect(dbus_object, "handle-unlink-record",
+                       G_CALLBACK(_handle_unlink_record), NULL);
 
        ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(dbus_object),
                        conn, CAL_DBUS_OBJPATH, &error);
index c944316..609e909 100644 (file)
@@ -47,6 +47,7 @@ static inline int __remake_db_file(void)
        if (SQLITE_OK != ret) {
                /* LCOV_EXCL_START */
                ERR("sqlite3_exec() Fail[%s]", errmsg);
+               ERR("[%s]", schema_query);
                sqlite3_free(errmsg);
                db_util_close(db);
                return -1;
index ec0b14d..61d2518 100644 (file)
@@ -25,7 +25,7 @@
 #include "cal_internal.h"
 #include "cal_db.h"
 
-#define __USER_VERSION 107
+#define __USER_VERSION 108
 
 /* LCOV_EXCL_START */
 static int _cal_server_update_get_db_version(sqlite3 *db, int *version)
@@ -222,7 +222,7 @@ int cal_server_update(void)
                 * added field is_alldy on schedule_table
                 */
 
-               /* add field: is_allday in deleted_table */
+               /* add field: is_allday in schedule_table */
                ret = sqlite3_exec(__db, "ALTER TABLE schedule_table ADD COLUMN is_allday INTEGER DEFAULT 0", NULL, 0, &errmsg);
                if (SQLITE_OK != ret) {
                        ERR("ALTER TABLE schedule_table failed(%d:%s)", ret, errmsg);
@@ -313,9 +313,86 @@ int cal_server_update(void)
                }
                /* ----------------------- end modified 2016/09/06
                */
+               old_version = 107;
+       }
+       if (old_version == 107) {
+               /*
+                * ----------------------- start modified 2017/04/17
+                */
+
+               /* add field: link_count in schedule_table */
+               ret = sqlite3_exec(__db, "ALTER TABLE schedule_table ADD COLUMN link_count INTEGER DEFAULT 0", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       ERR("ALTER TABLE schedule_table failed(%d:%s)", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+               /* add field: link_base_id in schedule_table */
+               ret = sqlite3_exec(__db, "ALTER TABLE schedule_table ADD COLUMN link_base_id INTEGER DEFAULT 0", NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       ERR("ALTER TABLE schedule_table failed(%d:%s)", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+               /* add trigger: update record when link_count is modified */
+               ret = sqlite3_exec(__db,
+                               "CREATE TRIGGER trg_link_mod AFTER UPDATE OF link_count ON schedule_table "
+                               " BEGIN "
+                               "       UPDATE schedule_table SET link_count = link_count + (SELECT link_count FROM schedule_table WHERE link_base_id = new.id) WHERE id = new.id; " /* base is linked to new base */
+                               "       UPDATE schedule_table SET link_base_id = new.id WHERE link_base_id = (SELECT id FROM schedule_table WHERE link_base_id = new.id); " /* new is linked to base */
+                               "       UPDATE schedule_table SET link_count = 0 WHERE link_base_id = new.id; " /* set count 0 */
+                               " END; ",
+                               NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       ERR("CREATE TRIGGER trg_link_mod failed(%d:%s)", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+               /* add trigger: update record when link record is deleted */
+               ret = sqlite3_exec(__db,
+                               "CREATE TRIGGER trg_link_del BEFORE DELETE ON schedule_table "
+                               " BEGIN "
+                               "       UPDATE schedule_table SET link_base_id = 0 WHERE link_base_id = old.id; " /* when base record is deleted. */
+                               "       UPDATE schedule_table SET link_count = link_count -1 WHERE id = old.link_base_id; " /* when linked record is deleted. */
+                               " END; ",
+                               NULL, 0, &errmsg);
+               if (SQLITE_OK != ret) {
+                       ERR("CREATE TRIGGER trg_link_mod failed(%d:%s)", ret, errmsg);
+                       sqlite3_free(errmsg);
+               }
+
+                /* ----------------------- end modified 2017/04/17
+                */
                old_version = __USER_VERSION;
        }
 
+       /* drop views */
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] event_view");
+       ret = sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       if (SQLITE_OK != ret) {
+               ERR("sqlite3_exec() failed(%d) [%s]", ret, errmsg);
+               sqlite3_free(errmsg);
+               db_util_close(__db);
+               return CALENDAR_ERROR_SYSTEM;
+       }
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] todo_view");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] todo_view");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] event_book_view");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] todo_book_view");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] event_calendar_attendee_view");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] utime_instance_view");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] localtime_instance_view");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] utime_instance_view_extended");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+       snprintf(query, sizeof(query), "DROP VIEW [IF EXISTS] localtime_instance_view_extended");
+       sqlite3_exec(__db, query, NULL, 0, &errmsg);
+
+
        /* update DB user_version */
        snprintf(query, sizeof(query), "PRAGMA user_version = %d", __USER_VERSION);
        ret = sqlite3_exec(__db, query, NULL, 0, &errmsg);
index 2599eaf..2f7759c 100644 (file)
@@ -68,7 +68,8 @@
                                "A.dtstart_type, A.dtstart_utime, A.dtstart_datetime, A.dtstart_tzid, "\
                                "A.dtend_type, A.dtend_utime, A.dtend_datetime, A.dtend_tzid, "\
                                "A.last_mod, A.rrule_id, A.recurrence_id, A.rdate, A.has_attendee, A.has_alarm, A.system_type, A.updated, "\
-                               "A.sync_data1, A.sync_data2, A.sync_data3, A.sync_data4, A.has_exception, A.has_extended, A.freq, A.is_allday "
+                               "A.sync_data1, A.sync_data2, A.sync_data3, A.sync_data4, A.has_exception, A.has_extended, A.freq, "\
+                               "A.is_allday, A.link_count, A.link_base_id "
 
 typedef int (*cal_db_get_record_cb)(int id, calendar_record_h* out_record);
 typedef int (*cal_db_insert_record_cb)(calendar_record_h record, int* id);
@@ -125,4 +126,7 @@ int cal_db_get_changes_exception_by_version(const char* view_uri, int original_e
 int cal_db_append_string(char **dst, const char *src);
 cal_db_plugin_cb_s* _cal_db_get_plugin(cal_record_type_e type);
 
+int cal_db_link_record(int base_id, int record_id);
+int cal_db_unlink_record(int record_id);
+
 #endif /* __CAL_DB_H__ */
diff --git a/server/db/cal_db_link.c b/server/db/cal_db_link.c
new file mode 100644 (file)
index 0000000..bbedd28
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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_typedef.h"
+#include "cal_view.h"
+#include "cal_record.h"
+#include "cal_db.h"
+#include "cal_db_util.h"
+#include "cal_db_plugin_event.h"
+#include "cal_db_plugin_event_helper.h"
+#include "cal_db_plugin_attendee_helper.h"
+#include "cal_db_plugin_alarm_helper.h"
+#include "cal_db_plugin_extended_helper.h"
+
+int cal_db_link_record(int base_id, int record_id)
+{
+       int ret = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+
+       ret = cal_db_util_begin_trans();
+       RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_begin_trans() Fail");
+
+       calendar_record_h record = NULL;
+       ret = cal_db_get_record(_calendar_event._uri, record_id, &record);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_get_record() Fail(%d)", ret);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+
+       /* base record and linked record have even type */
+       snprintf(query, sizeof(query), "UPDATE "CAL_TABLE_SCHEDULE" SET link_base_id = %d "
+                       "WHERE id = %d AND type = %d "
+                       "AND (SELECT type FROM "CAL_TABLE_SCHEDULE" WHERE id = %d) = %d ",
+                       base_id, record_id, CALENDAR_BOOK_TYPE_EVENT, base_id, CALENDAR_BOOK_TYPE_EVENT);
+
+       ret = cal_db_util_query_exec(query);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_exec() Fail(%d)", ret);
+               SECURE("[%s]", query);
+               calendar_record_destroy(record, true);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+
+       /* update base record's link_count */
+       snprintf(query, sizeof(query), "UPDATE "CAL_TABLE_SCHEDULE" SET link_count = link_count + 1 "
+                       "WHERE id = %d ", base_id);
+
+       ret = cal_db_util_query_exec(query);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_exec() Fail(%d)", ret);
+               SECURE("[%s]", query);
+               calendar_record_destroy(record, true);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+
+       /* To check alarm, attendee, exception, extended
+        * case 1: merge alarm
+        * case 2: remove linked record alarm
+        * we choose case 1. so modify alarm logic not to pick liked record alarm.
+        */
+
+       calendar_record_destroy(record, true);
+       cal_db_util_end_trans(true);
+
+       return ret;
+}
+
+int cal_db_unlink_record(int record_id)
+{
+       int ret = 0;
+       int base_id = 0;
+       char query[CAL_DB_SQL_MAX_LEN] = {0};
+
+       ret = cal_db_util_begin_trans();
+       RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_begin_trans() Fail");
+
+       /* get record */
+       calendar_record_h record = NULL;
+       ret = cal_db_get_record(_calendar_event._uri, record_id, &record);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_get_record() Fail(%d)", ret);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+       cal_event_s *event = (cal_event_s *)record;
+       base_id = event->link_base_id;
+
+       /* update base record's link_count */
+       snprintf(query, sizeof(query), "UPDATE "CAL_TABLE_SCHEDULE" SET link_count = link_count - 1 "
+                       "WHERE id = %d AND link_count > 0", base_id);
+
+       ret = cal_db_util_query_exec(query);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_exec() Fail(%d)", ret);
+               SECURE("[%s]", query);
+               calendar_record_destroy(record, true);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+
+       /* base record and linked record have even type */
+       snprintf(query, sizeof(query), "UPDATE "CAL_TABLE_SCHEDULE" SET link_base_id = 0 "
+                       "WHERE id = %d AND type = %d "
+                       "AND (SELECT type FROM "CAL_TABLE_SCHEDULE" WHERE id = %d) = %d ",
+                       record_id, CALENDAR_BOOK_TYPE_EVENT, base_id, CALENDAR_BOOK_TYPE_EVENT);
+
+       ret = cal_db_util_query_exec(query);
+       if (CALENDAR_ERROR_NONE != ret) {
+               /* LCOV_EXCL_START */
+               ERR("cal_db_util_query_exec() Fail(%d)", ret);
+               SECURE("[%s]", query);
+               calendar_record_destroy(record, true);
+               cal_db_util_end_trans(false);
+               return ret;
+               /* LCOV_EXCL_STOP */
+       }
+
+       calendar_record_destroy(record, true);
+       cal_db_util_end_trans(true);
+
+       return ret;
+}
+
diff --git a/server/db/cal_db_link.h b/server/db/cal_db_link.h
new file mode 100644 (file)
index 0000000..44ddd2d
--- /dev/null
@@ -0,0 +1,26 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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_DB_LINK_H__
+#define __CAL_DB_LINK_H__
+
+int cal_db_link_record(int base_id, int record_id);
+int cal_db_unlink_record(int record_id);
+
+#endif /*  __CAL_DB_LINK_H__ */
index eaabdc9..45a1b7c 100644 (file)
@@ -55,10 +55,10 @@ static int __update_record(calendar_record_h record, int is_dirty_in_time);
 /*
  * static function
  */
-static void _cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record, int *exception, int *extended);
+void cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record, int *exception, int *extended);
 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_exception_get_records(int original_id, cal_list_s *list);
+int cal_db_event_exception_get_records(int original_id, cal_list_s *list);
 static int _cal_db_event_exception_get_ids(int original_id, GList **out_list);
 static int _cal_db_event_exception_update(cal_list_s *exception_list_s, int original_id, int calendar_id, int is_dirty_in_time, time_t time_diff, int old_type, int new_type);
 static int _cal_db_event_get_deleted_data(int id, int* calendar_book_id, int* created_ver, int* original_event_id, char** recurrence_id);
@@ -174,7 +174,7 @@ static int _cal_db_event_get_record(int id, calendar_record_h* out_record)
                /* LCOV_EXCL_STOP */
        }
 
-       _cal_db_event_get_stmt(stmt, false, *out_record, &exception, &extended);
+       cal_db_event_get_stmt(stmt, false, *out_record, &exception, &extended);
        sqlite3_finalize(stmt);
        stmt = NULL;
 
@@ -207,7 +207,7 @@ static int _cal_db_event_get_record(int id, calendar_record_h* out_record)
                cal_db_attendee_get_records(event->index, event->attendee_list);
 
        if (exception == 1)
-               _cal_db_event_exception_get_records(event->index, event->exception_list);
+               cal_db_event_exception_get_records(event->index, event->exception_list);
 
        if (extended == 1)
                cal_db_extended_get_records(event->index, CALENDAR_RECORD_TYPE_EVENT, event->extended_list);
@@ -1092,7 +1092,7 @@ static int _cal_db_event_get_all_records(int offset, int limit, calendar_list_h*
                        return ret;
                        /* LCOV_EXCL_STOP */
                }
-               _cal_db_event_get_stmt(stmt, true, record, &exception, &extended);
+               cal_db_event_get_stmt(stmt, true, record, &exception, &extended);
 
                /* child */
                int has_attendee = 0, has_alarm = 0;
@@ -1109,7 +1109,7 @@ static int _cal_db_event_get_all_records(int offset, int limit, calendar_list_h*
                }
 
                if (exception == 1)
-                       _cal_db_event_exception_get_records(record_id, pevent->exception_list);
+                       cal_db_event_exception_get_records(record_id, pevent->exception_list);
 
                if (extended == 1)
                        cal_db_extended_get_records(record_id, CALENDAR_RECORD_TYPE_EVENT, pevent->extended_list);
@@ -1279,34 +1279,28 @@ static int _cal_db_event_get_records_with_query(calendar_query_h query, int offs
                        return ret;
                        /* LCOV_EXCL_STOP */
                }
+
+               cal_event_s* pevent = (cal_event_s*)record;
                if (0 < que->projection_count) {
                        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_event_s *event = NULL;
-                       _cal_db_event_get_stmt(stmt, true, record, &exception, &extended);
-                       event = (cal_event_s*)(record);
-                       if (event) {
-                               attendee = event->has_attendee;
-                               alarm = event->has_alarm;
-                       }
+                       cal_db_event_get_stmt(stmt, true, record, &exception, &extended);
+                       attendee = pevent->has_attendee;
+                       alarm = pevent->has_alarm;
                }
 
                /* child */
                if (cal_db_query_find_projection_property(query, CAL_PROPERTY_EVENT_CALENDAR_ALARM) == true && alarm == 1) {
-                       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 && attendee == 1) {
-                       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 && exception == 1) {
-                       cal_event_s* pevent = (cal_event_s*) record;
-                       _cal_db_event_exception_get_records(pevent->index, pevent->exception_list);
+                       cal_db_event_exception_get_records(pevent->index, pevent->exception_list);
                }
                if (cal_db_query_find_projection_property(query, CAL_PROPERTY_EVENT_EXTENDED) == true && extended == 1) {
-                       cal_event_s* pevent = (cal_event_s*) record;
                        cal_db_extended_get_records(pevent->index, CALENDAR_RECORD_TYPE_EVENT, pevent->extended_list);
                }
 
@@ -1723,7 +1717,7 @@ static int _cal_db_event_replace_record(calendar_record_h record, int id)
        return CALENDAR_ERROR_NONE;
 }
 
-static void _cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record,
+void cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record,
                int *exception, int *extended)
 {
        cal_event_s *event = NULL;
@@ -1845,6 +1839,8 @@ static void _cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calen
 
        event->freq = sqlite3_column_int(stmt, count++);
        event->is_allday = sqlite3_column_int(stmt, count++);
+       event->link_count = sqlite3_column_int(stmt, count++);
+       event->link_base_id = sqlite3_column_int(stmt, count++);
 
        if (is_view_table == true) {
                if (event->freq <= 0)
@@ -2146,6 +2142,12 @@ static void _cal_db_event_get_property_stmt(sqlite3_stmt *stmt,
        case CAL_PROPERTY_EVENT_IS_ALLDAY:
                event->is_allday = sqlite3_column_int(stmt, *stmt_count);
                break;
+       case CAL_PROPERTY_EVENT_LINK_COUNT:
+               event->link_count = sqlite3_column_int(stmt, *stmt_count);
+               break;
+       case CAL_PROPERTY_EVENT_LINK_BASE_ID:
+               event->link_base_id = sqlite3_column_int(stmt, *stmt_count);
+               break;
        default:
                /* LCOV_EXCL_START */
                ERR("invalid (0x%x)", property);
@@ -2373,7 +2375,7 @@ static int _cal_db_event_update_dirty(calendar_record_h record, int is_dirty_in_
        return ret;
 }
 
-static int _cal_db_event_exception_get_records(int original_id, cal_list_s *list)
+int cal_db_event_exception_get_records(int original_id, cal_list_s *list)
 {
        int ret;
        char query[CAL_DB_SQL_MAX_LEN] = {0};
@@ -2411,7 +2413,7 @@ static int _cal_db_event_exception_get_records(int original_id, cal_list_s *list
                        /* LCOV_EXCL_STOP */
                }
 
-               _cal_db_event_get_stmt(stmt, false, record, &exception, &extended);
+               cal_db_event_get_stmt(stmt, false, record, &exception, &extended);
 
                cal_rrule_s *rrule = NULL;
                cal_event_s *event = (cal_event_s *)record;
@@ -2430,7 +2432,7 @@ static int _cal_db_event_exception_get_records(int original_id, cal_list_s *list
                        cal_db_attendee_get_records(event->index, event->attendee_list);
 
                if (exception == 1)
-                       _cal_db_event_exception_get_records(event->index, event->exception_list);
+                       cal_db_event_exception_get_records(event->index, event->exception_list);
 
                if (extended == 1)
                        cal_db_extended_get_records(event->index, CALENDAR_RECORD_TYPE_EVENT, event->extended_list);
diff --git a/server/db/cal_db_plugin_event.h b/server/db/cal_db_plugin_event.h
new file mode 100644 (file)
index 0000000..e8f3007
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Calendar Service
+ *
+ * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __CAL_DB_PLUGIN_EVENT_H__
+#define __CAL_DB_PLUGIN_EVENT_H__
+
+void cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record,
+               int *exception, int *extended);
+int cal_db_event_exception_get_records(int original_id, cal_list_s *list);
+
+#endif /* __CAL_DB_PLUGIN_EVENT_H__ */
index eca9993..c10b3e9 100644 (file)
@@ -578,9 +578,8 @@ static void _cal_db_instance_localtime_get_property_stmt(sqlite3_stmt *stmt,
                instance->sync_data1 = cal_strdup((const char*)temp);
                break;
        case CAL_PROPERTY_INSTANCE_LOCALTIME_IS_ALLDAY:
-               instance->is_allday = sqlite3_column_int64(stmt, *stmt_count);
+               instance->is_allday = sqlite3_column_int(stmt, *stmt_count);
                break;
-
        default:
                sqlite3_column_int(stmt, *stmt_count);
                break;
index f650a31..d1ade7a 100644 (file)
@@ -1122,6 +1122,8 @@ static int _cal_db_todo_get_records_with_query(calendar_query_h query, int offse
                        return ret;
                        /* LCOV_EXCL_STOP */
                }
+
+               cal_todo_s* ptodo = (cal_todo_s*)record;
                if (0 < que->projection_count) {
                        cal_record_set_projection(record,
                                        que->projection, que->projection_count, que->property_count);
@@ -1130,27 +1132,20 @@ static int _cal_db_todo_get_records_with_query(calendar_query_h query, int offse
                                        que->projection, que->projection_count,
                                        record);
                } else {
-                       cal_todo_s *todo = NULL;
                        _cal_db_todo_get_stmt(stmt, true, record, &extended);
-                       todo = (cal_todo_s*)(record);
-                       if (todo) {
-                               attendee = todo->has_attendee;
-                               alarm = todo->has_alarm;
-                       }
+                       attendee = ptodo->has_attendee;
+                       alarm = ptodo->has_alarm;
                }
 
                /* child */
                if (cal_db_query_find_projection_property(query, CAL_PROPERTY_TODO_CALENDAR_ALARM) == true && alarm == 1) {
-                       cal_todo_s* todo = (cal_todo_s*) record;
-                       cal_db_alarm_get_records(todo->index, todo->alarm_list);
+                       cal_db_alarm_get_records(ptodo->index, ptodo->alarm_list);
                }
                if (cal_db_query_find_projection_property(query, CAL_PROPERTY_TODO_CALENDAR_ATTENDEE) == true && attendee == 1) {
-                       cal_todo_s* todo = (cal_todo_s*) record;
-                       cal_db_attendee_get_records(todo->index, todo->attendee_list);
+                       cal_db_attendee_get_records(ptodo->index, ptodo->attendee_list);
                }
                if (cal_db_query_find_projection_property(query, CAL_PROPERTY_TODO_EXTENDED) == true && extended == 1) {
-                       cal_todo_s* todo = (cal_todo_s*) record;
-                       cal_db_extended_get_records(todo->index, CALENDAR_RECORD_TYPE_TODO, todo->extended_list);
+                       cal_db_extended_get_records(ptodo->index, CALENDAR_RECORD_TYPE_TODO, ptodo->extended_list);
                }
 
                ret = calendar_list_add(*out_list, record);
@@ -1416,6 +1411,8 @@ static void _cal_db_todo_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calend
 
        todo->freq = sqlite3_column_int(stmt, count++);
        todo->is_allday = sqlite3_column_int(stmt, count++);
+       count++; /* link_count */
+       count++; /* link_base_id */
 
        if (is_view_table == true) {
                if (todo->freq <= 0)