4 * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #include "cal_internal.h"
23 #include "cal_typedef.h"
25 #include "cal_record.h"
27 #include "cal_access_control.h"
28 #include "cal_db_query.h"
29 #include "cal_db_rrule.h"
30 #include "cal_db_query.h"
31 #include "cal_db_plugin_alarm_helper.h"
32 #include "cal_db_instance.h"
33 #include "cal_db_plugin_attendee_helper.h"
34 #include "cal_db_plugin_extended_helper.h"
35 #include "cal_db_plugin_event_helper.h"
36 #include "cal_db_plugin_timezone_helper.h"
38 #include "cal_db_util.h"
39 #include "cal_utils.h"
42 CAL_RECURRENCE_ID_RANGE_NONE,
43 CAL_RECURRENCE_ID_RANGE_THISANDFUTURE,
44 CAL_RECURRENCE_ID_RANGE_THISANDPRIOR,
45 CAL_RECURRENCE_ID_RANGE_MAX,
48 #define DEBUG_DATETIME(x) DBG("%04d-%02d-%02dT%02d:%02d:%02d",\
56 int cal_db_event_update_original_event_version(int original_event_id, int version)
59 char query[CAL_DB_SQL_MAX_LEN] = {0};
61 DBG("original_event(%d) changed_ver updated", original_event_id);
62 if (0 < original_event_id) {
63 snprintf(query, sizeof(query), "UPDATE %s SET changed_ver=%d, has_exception = 1 WHERE id=%d ",
64 CAL_TABLE_SCHEDULE, version, original_event_id);
66 ret = cal_db_util_query_exec(query);
67 if (CALENDAR_ERROR_NONE != ret) {
69 ERR("cal_db_util_query_exec() Fail(%d)", ret);
70 SECURE("[%s]", query);
75 return CALENDAR_ERROR_NONE;
78 int cal_db_event_check_value_validation(cal_event_s *event)
80 long long int slli = 0;
81 long long int elli = 0;
83 RETV_IF(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
85 if (event->start.type != event->end.type) {
87 ERR("normal end(%lld) < start(%lld)",
88 event->end.time.utime, event->start.time.utime);
89 return CALENDAR_ERROR_INVALID_PARAMETER;
93 switch (event->start.type) {
94 case CALENDAR_TIME_UTIME:
95 if (event->end.time.utime < event->start.time.utime) {
97 ERR("normal end(%lld) < start(%lld) so set same", event->end.time.utime, event->start.time.utime);
98 event->end.time.utime = event->start.time.utime;
99 return CALENDAR_ERROR_INVALID_PARAMETER;
104 case CALENDAR_TIME_LOCALTIME:
105 /* check invalid value */
106 if (event->start.time.date.month < 1 || 12 < event->start.time.date.month) {
107 /* LCOV_EXCL_START */
108 ERR("Error check start month(input:%d)", event->start.time.date.month);
109 return CALENDAR_ERROR_INVALID_PARAMETER;
111 } else if (event->start.time.date.mday < 1 || 31 < event->start.time.date.mday) {
112 /* LCOV_EXCL_START */
113 ERR("Error check start mday(input:%d)", event->start.time.date.mday);
114 return CALENDAR_ERROR_INVALID_PARAMETER;
116 } else if (event->end.time.date.month < 1 || 12 < event->end.time.date.month) {
117 /* LCOV_EXCL_START */
118 ERR("Error check end month(input:%d)", event->end.time.date.month);
119 return CALENDAR_ERROR_INVALID_PARAMETER;
121 } else if (event->end.time.date.mday < 1 || 31 < event->end.time.date.mday) {
122 /* LCOV_EXCL_START */
123 ERR("Error check end mday(input:%d)", event->end.time.date.mday);
124 return CALENDAR_ERROR_INVALID_PARAMETER;
127 /* handle hour, minute, second */
128 if (event->start.time.date.hour < 0 || 24 < event->start.time.date.hour)
129 event->start.time.date.hour = 0;
130 if (event->start.time.date.minute < 0 || 60 < event->start.time.date.minute)
131 event->start.time.date.minute = 0;
132 if (event->start.time.date.second < 0 || 60 < event->start.time.date.second)
133 event->start.time.date.second = 0;
134 if (event->end.time.date.hour < 0 || 24 < event->end.time.date.hour)
135 event->end.time.date.hour = 0;
136 if (event->end.time.date.minute < 0 || 60 < event->end.time.date.minute)
137 event->end.time.date.minute = 0;
138 if (event->end.time.date.second < 0 || 60 < event->end.time.date.second)
139 event->end.time.date.second = 0;
142 /* check end < start; convert long long int */
143 slli = cal_time_convert_itol(NULL,
144 event->start.time.date.year, event->start.time.date.month, event->start.time.date.mday,
145 event->start.time.date.hour, event->start.time.date.minute, event->start.time.date.second);
146 elli = cal_time_convert_itol(NULL,
147 event->end.time.date.year, event->end.time.date.month, event->end.time.date.mday,
148 event->end.time.date.hour, event->end.time.date.minute, event->end.time.date.second);
150 if (1 < slli - elli) {
151 /* 1 is to ignore milliseconds */
152 /* LCOV_EXCL_START */
153 ERR("allday end(%lld) < start(%lld) so set same", elli, slli);
154 return CALENDAR_ERROR_INVALID_PARAMETER;
160 return CALENDAR_ERROR_NONE;
163 GList* cal_db_event_get_list_with_uid(char *uid, int parent_id)
166 RETV_IF(NULL == uid, NULL);
167 RETV_IF('\0' == *uid, NULL);
169 char query[CAL_DB_SQL_MAX_LEN] = {0};
170 snprintf(query, sizeof(query), "SELECT id FROM %s WHERE original_event_id=-1 AND uid LIKE '%s' AND id!=%d",
171 CAL_TABLE_SCHEDULE, uid, parent_id);
173 sqlite3_stmt *stmt = NULL;
174 ret = cal_db_util_query_prepare(query, &stmt);
175 if (CALENDAR_ERROR_NONE != ret) {
176 /* LCOV_EXCL_START */
177 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
178 SECURE("query[%s]", query);
184 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
185 int id = sqlite3_column_int(stmt, 0);
186 l = g_list_append(l, GINT_TO_POINTER(id));
188 sqlite3_finalize(stmt);
192 void cal_db_event_update_child_origina_event_id(int child_id, int parent_id)
197 char query[CAL_DB_SQL_MAX_LEN] = {0};
198 snprintf(query, sizeof(query), "UPDATE %s SET original_event_id=%d WHERE id=%d",
199 CAL_TABLE_SCHEDULE, parent_id, child_id);
200 ret = cal_db_util_query_exec(query);
201 if (CALENDAR_ERROR_NONE != ret) {
202 /* LCOV_EXCL_START */
203 ERR("cal_db_util_query_exec() Fail(%d)", ret);
204 SECURE("[%s]", query);
209 char* cal_db_event_get_recurrence_id_from_exception(int child_id)
212 char query[CAL_DB_SQL_MAX_LEN] = {0};
213 snprintf(query, sizeof(query), "SELECT recurrence_id FROM %s WHERE id=%d",
214 CAL_TABLE_SCHEDULE, child_id);
216 sqlite3_stmt *stmt = NULL;
217 ret = cal_db_util_query_prepare(query, &stmt);
218 if (CALENDAR_ERROR_NONE != ret) {
219 /* LCOV_EXCL_START */
220 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
221 SECURE("query[%s]", query);
226 char *recurrence_id = NULL;
227 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
228 recurrence_id = cal_strdup((const char*)sqlite3_column_text(stmt, 0));
230 sqlite3_finalize(stmt);
231 return recurrence_id;
234 static void __get_tzid_and_range(char *p, char **out_tzid, int *out_range)
238 RET_IF(NULL == out_tzid);
239 RET_IF(NULL == out_range);
242 s = g_strsplit(p, ";", -1);
243 RETM_IF(NULL == s, "g_strsplit() Fail");
245 int count = g_strv_length(s);
248 int range = CAL_RECURRENCE_ID_RANGE_NONE;
249 for (i = 0; i < count; i++) {
250 if (NULL == s[i] || '\0' == *s[i])
253 if (CAL_STRING_EQUAL == strncmp(s[i], "TZID=", strlen("TZID="))) {
256 tzid = strdup(s[i] + strlen("TZID="));
257 DBG("tzid [%s]", tzid);
258 } else if (CAL_STRING_EQUAL == strncmp(s[i], "RANGE=", strlen("RANGE="))) {
259 char *param = s[i] + strlen("RANGE=");
260 if (CAL_STRING_EQUAL == strncmp(param, "THISANDFUTURE", strlen("THISANDFUTURE")))
261 range = CAL_RECURRENCE_ID_RANGE_THISANDFUTURE;
262 else if (CAL_STRING_EQUAL == strncmp(param, "THISANDPRIOR", strlen("THISANDPRIOR")))
263 range = CAL_RECURRENCE_ID_RANGE_THISANDPRIOR;
265 WARN("Invalid param[%s]", s[i]);
267 WARN("Invalid param[%s]", s[i]);
275 static void cal_db_event_apply_recurrence_id_child(int child_id, cal_event_s *event, calendar_time_s until, bool is_prior)
278 calendar_record_h record = NULL;
279 ret = cal_db_get_record(_calendar_event._uri, child_id, &record);
280 RETM_IF(CALENDAR_ERROR_NONE != ret, "cal_db_get_record() Fail(%d)", ret);
282 if (true == is_prior) {
283 cal_record_set_caltime(record, _calendar_event.start_time, event->start);
284 cal_record_set_caltime(record, _calendar_event.end_time, event->end);
285 switch (event->start.type) {
286 case CALENDAR_TIME_UTIME:
287 DBG("dtstart(%lld) dtend(%lld)", event->start.time.utime, event->end.time.utime);
289 case CALENDAR_TIME_LOCALTIME:
290 DBG("dtstart(%04d-%02d-%02dT%02d:%02d:%02d) dtend(%04d-%02d-%02dT%02d:%02d:%02d)",
291 event->start.time.date.year, event->start.time.date.month, event->start.time.date.mday,
292 event->start.time.date.hour, event->start.time.date.minute, event->start.time.date.second,
293 event->end.time.date.year, event->end.time.date.month, event->end.time.date.mday,
294 event->end.time.date.hour, event->end.time.date.minute, event->end.time.date.second);
299 cal_record_set_int(record, _calendar_event.freq, event->freq);
300 cal_record_set_int(record, _calendar_event.interval, event->interval);
301 cal_record_set_int(record, _calendar_event.wkst, event->wkst);
302 if (event->byyearday && *event->byyearday)
303 cal_record_set_str(record, _calendar_event.byyearday, event->byyearday);
304 if (event->byweekno && *event->byweekno)
305 cal_record_set_str(record, _calendar_event.byweekno, event->byweekno);
306 if (event->bymonth && *event->bymonth)
307 cal_record_set_str(record, _calendar_event.bymonth, event->bymonth);
308 if (event->bymonthday && *event->bymonthday)
309 cal_record_set_str(record, _calendar_event.bymonthday, event->bymonthday);
310 if (event->byday && *event->byday)
311 cal_record_set_str(record, _calendar_event.byday, event->byday);
312 if (event->bysetpos && *event->bysetpos)
313 cal_record_set_str(record, _calendar_event.bysetpos, event->bysetpos);
316 cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
317 cal_record_set_caltime(record, _calendar_event.until_time, until);
320 cal_record_set_str(record, _calendar_event.uid, "");
321 cal_record_set_int(record, _calendar_event.original_event_id, -1);
323 cal_db_update_record(record);
324 calendar_record_destroy(record, true);
326 static void __get_next_instance_caltime(int parent_id, calendar_time_s *caltime, calendar_time_s *dtstart, calendar_time_s *dtend)
329 char query[CAL_DB_SQL_MAX_LEN] = {0};
330 sqlite3_stmt *stmt = NULL;
332 switch (caltime->type) {
333 case CALENDAR_TIME_UTIME:
334 snprintf(query, sizeof(query), "SELECT dtstart_utime, dtend_utime FROM %s WHERE event_id=%d AND dtstart_utime>%lld "
335 "ORDER BY dtstart_utime ASC LIMIT 1",
336 CAL_TABLE_NORMAL_INSTANCE, parent_id, caltime->time.utime);
338 ret = cal_db_util_query_prepare(query, &stmt);
339 if (CALENDAR_ERROR_NONE != ret) {
340 /* LCOV_EXCL_START */
341 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
342 SECURE("query[%s]", query);
347 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
348 dtstart->type = CALENDAR_TIME_UTIME;
349 dtstart->time.utime = sqlite3_column_int64(stmt, 0);
350 dtend->type = CALENDAR_TIME_UTIME;
351 dtend->time.utime = sqlite3_column_int64(stmt, 0);
355 case CALENDAR_TIME_LOCALTIME:
356 snprintf(query, sizeof(query), "SELECT dtstart_datetime, dtend_datetime FROM %s "
357 "WHERE event_id=%d AND dtstart_datetime>'%04d-%02d-%02dT%02d:%02d:%02d' "
358 "ORDER BY dtstart_datetime ASC LIMIT 1",
359 CAL_TABLE_ALLDAY_INSTANCE, parent_id,
360 caltime->time.date.year, caltime->time.date.month, caltime->time.date.mday,
361 caltime->time.date.hour, caltime->time.date.minute, caltime->time.date.second);
363 ret = cal_db_util_query_prepare(query, &stmt);
364 if (CALENDAR_ERROR_NONE != ret) {
365 /* LCOV_EXCL_START */
366 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
367 SECURE("query[%s]", query);
372 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
374 dtstart->type = CALENDAR_TIME_LOCALTIME;
375 temp = (char *)sqlite3_column_text(stmt, 0);
377 sscanf(temp, CAL_FORMAT_LOCAL_DATETIME,
378 &(dtstart->time.date.year), &(dtstart->time.date.month), &(dtstart->time.date.mday),
379 &(dtstart->time.date.hour), &(dtstart->time.date.minute), &(dtstart->time.date.second));
381 dtend->type = CALENDAR_TIME_LOCALTIME;
382 temp = (char *)sqlite3_column_text(stmt, 1);
384 sscanf(temp, CAL_FORMAT_LOCAL_DATETIME,
385 &(dtend->time.date.year), &(dtend->time.date.month), &(dtend->time.date.mday),
386 &(dtend->time.date.hour), &(dtend->time.date.minute), &(dtend->time.date.second));
391 sqlite3_finalize(stmt);
393 static void __get_last_instance_caltime(int parent_id, int type, calendar_time_s *dtstart)
396 char query[CAL_DB_SQL_MAX_LEN] = {0};
397 sqlite3_stmt *stmt = NULL;
400 case CALENDAR_TIME_UTIME:
401 snprintf(query, sizeof(query), "SELECT dtstart_utime FROM %s WHERE event_id=%d "
402 "ORDER BY dtstart_utime DESC LIMIT 1",
403 CAL_TABLE_NORMAL_INSTANCE, parent_id);
404 ret = cal_db_util_query_prepare(query, &stmt);
405 if (CALENDAR_ERROR_NONE != ret) {
406 /* LCOV_EXCL_START */
407 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
408 SECURE("query[%s]", query);
412 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
413 dtstart->type = CALENDAR_TIME_UTIME;
414 dtstart->time.utime = sqlite3_column_int64(stmt, 0);
418 case CALENDAR_TIME_LOCALTIME:
419 snprintf(query, sizeof(query), "SELECT dtstart_datetime FROM %s WHERE event_id=%d "
420 "ORDER BY dtstart_datetime DESC LIMIT 1",
421 CAL_TABLE_ALLDAY_INSTANCE, parent_id);
422 ret = cal_db_util_query_prepare(query, &stmt);
423 if (CALENDAR_ERROR_NONE != ret) {
424 /* LCOV_EXCL_START */
425 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
426 SECURE("query[%s]", query);
430 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
432 dtstart->type = CALENDAR_TIME_LOCALTIME;
433 temp = (char *)sqlite3_column_text(stmt, 0);
435 sscanf(temp, CAL_FORMAT_LOCAL_DATETIME,
436 &(dtstart->time.date.year), &(dtstart->time.date.month), &(dtstart->time.date.mday),
437 &(dtstart->time.date.hour), &(dtstart->time.date.minute), &(dtstart->time.date.second));
439 WARN("datetime is NULL");
444 sqlite3_finalize(stmt);
447 static void __del_recurence_id_instance(calendar_time_s *rectime, int parent_id)
450 char query[CAL_DB_SQL_MAX_LEN] = {0};
451 switch (rectime->type) {
452 case CALENDAR_TIME_UTIME:
453 snprintf(query, sizeof(query), "DELETE FROM %s WHERE dtstart_utime=%lld AND event_id=%d",
454 CAL_TABLE_NORMAL_INSTANCE, rectime->time.utime, parent_id);
456 case CALENDAR_TIME_LOCALTIME:
457 snprintf(query, sizeof(query), "DELETE FROM %s WHERE dtstart_datetime='%04d-%02d-%02dT%02d:%02d:%02d' AND event_id=%d",
458 CAL_TABLE_ALLDAY_INSTANCE, rectime->time.date.year, rectime->time.date.month, rectime->time.date.mday,
459 rectime->time.date.hour, rectime->time.date.minute, rectime->time.date.second, parent_id);
462 ret = cal_db_util_query_exec(query);
463 if (CALENDAR_ERROR_NONE != ret) {
464 /* LCOV_EXCL_START */
465 ERR("cal_db_util_query_exec() Fail(%d)", ret);
466 SECURE("[%s]", query);
471 int y = 0, m = 0, d = 0;
472 int h = 0, n = 0, s = 0;
473 switch (rectime->type) {
474 case CALENDAR_TIME_UTIME:
475 cal_time_get_datetime(rectime->time.utime, &y, &m, &d, &h, &n, &s);
476 DBG("[DELETED] %04d-%02d-%02dT%02d:%02d:%02d (utime)", y, m, d, h, n, s);
478 case CALENDAR_TIME_LOCALTIME:
479 DBG("[DELETED] %04d-%02d-%02dT%02d:%02d:%02d (local)",
480 rectime->time.date.year, rectime->time.date.month, rectime->time.date.mday,
481 rectime->time.date.hour, rectime->time.date.minute, rectime->time.date.second);
486 static void __set_original_event_id_in_child(int child_id, int parent_id)
489 char query[CAL_DB_SQL_MAX_LEN] = {0};
490 snprintf(query, sizeof(query), "UPDATE %s SET original_event_id=%d WHERE id=%d",
491 CAL_TABLE_SCHEDULE, parent_id, child_id);
493 ret = cal_db_util_query_exec(query);
494 if (CALENDAR_ERROR_NONE != ret) {
495 /* LCOV_EXCL_START */
496 ERR("cal_db_util_query_exec() Fail(%d)", ret);
497 SECURE("[%s]", query);
503 * RECURRENCE-ID;VALUE=DATE:19960401
504 * RECURRENCE-ID;RANGE=THISANDFUTURE:19960120T120000Z
505 * RECURRENCE-ID;RANGE=THISANDPRIOR:19980401T133000Z
506 * RECURRENCE-ID;TZID=Asia/Seoul:20150106T090000
508 void cal_db_event_apply_recurrence_id(int parent_id, cal_event_s *event, char *recurrence_id, int child_id)
512 RET_IF(NULL == recurrence_id);
513 RET_IF('\0' == *recurrence_id);
516 t = g_strsplit(recurrence_id, ":", -1);
517 RETM_IF(NULL == t, "g_strsplit() Fail");
519 if ('\0' == *t[0]) { /* no param */
523 int count = g_strv_length(t);
524 int len_param = strlen(t[count -1]);
525 *(recurrence_id + strlen(recurrence_id) - len_param -1) = '\0';
528 char *datetime = recurrence_id + strlen(recurrence_id) +1;
529 int len_datetime = strlen(datetime);
530 DBG("datetime[%s]", datetime);
533 int range = CAL_RECURRENCE_ID_RANGE_NONE;
534 __get_tzid_and_range(recurrence_id, &tzid, &range);
536 int y = 0, m = 0, d = 0;
537 int h = 0, n = 0, s = 0;
538 char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
539 long long int dtstart_utime = 0;
540 calendar_time_s rectime = {0};
541 switch (len_datetime) {
543 sscanf(datetime, CAL_DATETIME_FORMAT_YYYYMMDD, &y, &m, &d);
544 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME, y, m, d, 0, 0, 0);
545 rectime.type = CALENDAR_TIME_LOCALTIME;
546 rectime.time.date.year = y;
547 rectime.time.date.month = m;
548 rectime.time.date.mday = d;
549 rectime.time.date.hour = 0;
550 rectime.time.date.minute = 0;
551 rectime.time.date.second = 0;
554 sscanf(datetime, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS, &y, &m, &d, &h, &n, &s);
556 dtstart_utime = cal_time_convert_itol(tzid, y, m, d, h, n, s);
557 rectime.type = CALENDAR_TIME_UTIME;
558 rectime.time.utime = dtstart_utime;
560 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME, y, m, d, h, n, s);
561 rectime.type = CALENDAR_TIME_LOCALTIME;
562 rectime.time.date.year = y;
563 rectime.time.date.month = m;
564 rectime.time.date.mday = d;
565 rectime.time.date.hour = h;
566 rectime.time.date.minute = n;
567 rectime.time.date.second = s;
571 sscanf(datetime, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, &y, &m, &d, &h, &n, &s);
572 dtstart_utime = cal_time_convert_itol(tzid, y, m, d, h, n, s);
573 rectime.type = CALENDAR_TIME_UTIME;
574 rectime.time.utime = dtstart_utime;
579 calendar_time_s until = {0};
580 calendar_time_s dtstart = {0};
581 calendar_time_s dtend = {0};
582 calendar_record_h record = (calendar_record_h)event;
584 case CAL_RECURRENCE_ID_RANGE_THISANDFUTURE:
586 switch (event->range_type) {
587 case CALENDAR_RANGE_UNTIL:
588 case CALENDAR_RANGE_NONE:
589 until = event->start;
591 case CALENDAR_RANGE_COUNT:
592 __get_last_instance_caltime(parent_id, rectime.type, &until);
595 cal_db_event_apply_recurrence_id_child(child_id, event, until, false);
597 DBG("update parent");
599 cal_time_modify_caltime(&until, -1);
600 cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
601 cal_record_set_caltime(record, _calendar_event.until_time, until);
602 cal_record_set_str(record, _calendar_event.recurrence_id, "");
603 cal_record_set_str(record, _calendar_event.uid, "");
604 cal_db_update_record(record);
606 case CAL_RECURRENCE_ID_RANGE_THISANDPRIOR:
609 cal_db_event_apply_recurrence_id_child(child_id, event, until, true);
611 DBG("update parent");
612 __get_next_instance_caltime(parent_id, &until, &dtstart, &dtend);
613 cal_record_set_caltime(record, _calendar_event.start_time, dtstart);
614 cal_record_set_caltime(record, _calendar_event.end_time, dtend);
615 switch (event->range_type) {
616 case CALENDAR_RANGE_UNTIL:
617 case CALENDAR_RANGE_NONE:
619 case CALENDAR_RANGE_COUNT:
620 __get_last_instance_caltime(parent_id, rectime.type, &until);
621 cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
622 cal_record_set_caltime(record, _calendar_event.until_time, until);
623 DBG(CAL_FORMAT_LOCAL_DATETIME,
624 until.time.date.year, until.time.date.month, until.time.date.mday,
625 until.time.date.hour, until.time.date.minute, until.time.date.second);
628 cal_record_set_str(record, _calendar_event.recurrence_id, "");
629 cal_db_update_record(record);
632 __del_recurence_id_instance(&rectime, parent_id);
633 __set_original_event_id_in_child(child_id, parent_id);
637 static int __get_parent_id_with_uid(char *uid, int child_id)
640 char query[CAL_DB_SQL_MAX_LEN] = {0};
642 snprintf(query, sizeof(query), "SELECT id FROM %s WHERE original_event_id=-1 AND id!=%d AND uid='%s'",
643 CAL_TABLE_SCHEDULE, child_id, uid);
645 sqlite3_stmt *stmt = NULL;
646 ret = cal_db_util_query_prepare(query, &stmt);
647 if (CALENDAR_ERROR_NONE != ret) {
648 /* LCOV_EXCL_START */
649 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
650 SECURE("query[%s]", query);
654 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
655 parent_id = sqlite3_column_int64(stmt, 0);
657 sqlite3_finalize(stmt);
658 DBG("found parent_id(%d)", parent_id);
662 int cal_db_event_insert_record(calendar_record_h record, int original_event_id, int *id)
668 char query[CAL_DB_SQL_MAX_LEN] = {0};
669 char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
670 char dtend_datetime[CAL_STR_SHORT_LEN32] = {0};
671 sqlite3_stmt *stmt = NULL;
672 cal_event_s* event = (cal_event_s*)(record);
673 cal_rrule_s *rrule = NULL;
675 int calendar_book_id = 0;
676 calendar_record_h record_calendar = NULL;
680 RETV_IF(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
682 ret = cal_db_event_check_value_validation(event);
683 if (CALENDAR_ERROR_NONE != ret) {
684 /* LCOV_EXCL_START */
685 ERR("cal_db_event_check_value_validation() Fail(%d)", ret);
691 if (cal_access_control_have_write_permission(event->calendar_id) == false) {
692 /* LCOV_EXCL_START */
693 ERR("cal_access_control_have_write_permission() Fail");
694 return CALENDAR_ERROR_PERMISSION_DENIED;
698 ret = calendar_record_get_int(record, _calendar_event.calendar_book_id, &calendar_book_id);
699 DBG("calendar_book_id(%d)", calendar_book_id);
701 ret = cal_db_get_record(_calendar_book._uri, calendar_book_id, &record_calendar);
702 RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "cal_db_get_record() Fail(%d)", ret);
704 calendar_record_destroy(record_calendar, true);
706 has_alarm = cal_db_alarm_has_alarm(event->alarm_list);
707 cal_db_timezone_search_with_tzid(event->calendar_id, event->start_tzid, &timezone_id);
708 input_ver = cal_db_util_get_next_ver();
711 if (CALENDAR_TIME_LOCALTIME == event->start.type
712 && (0 == event->start.time.date.hour)
713 && (0 == event->start.time.date.minute)
714 && (0 == event->start.time.date.second)
715 && (0 == event->end.time.date.hour)
716 && (0 == event->end.time.date.minute)
717 && (0 == event->end.time.date.second)) {
721 snprintf(query, sizeof(query), "INSERT INTO %s ("
723 "created_ver, changed_ver, "
724 "summary, description, location, categories, exdate, "
725 "task_status, priority, "
727 "contact_id, busy_status, sensitivity, uid, "
728 "organizer_name, organizer_email, meeting_status, "
730 "original_event_id, "
731 "latitude, longitude, "
733 "created_time, completed_time, progress, "
734 "dtstart_type, dtstart_utime, dtstart_datetime, dtstart_tzid, "
735 "dtend_type, dtend_utime, dtend_datetime, dtend_tzid, "
736 "last_mod, rrule_id, "
737 "recurrence_id, rdate, has_attendee, "
738 "has_alarm, system_type, updated, "
739 "sync_data1, sync_data2, sync_data3, sync_data4,"
740 "has_exception, has_extended, freq, is_allday "
753 "strftime('%%s', 'now'), %lld, %d, "
756 "strftime('%%s', 'now'), %d, "
757 "?, ?, %d, %d, %d, %d, "
761 CAL_SCH_TYPE_EVENT, /*event->cal_type,*/
762 input_ver, input_ver,
763 event->event_status, event->priority,
764 event->timezone ? event->timezone : timezone_id,
765 event->contact_id, event->busy_status, event->sensitivity,
766 event->meeting_status,
769 event->latitude, event->longitude,
771 (long long int)0, 0, /* event->completed_time, event->progress */
772 event->start.type, event->start.type == CALENDAR_TIME_UTIME ? event->start.time.utime : 0,
773 event->end.type, event->end.type == CALENDAR_TIME_UTIME ? event->end.time.utime : 0,
774 0 < event->freq ? 1 : 0,
775 (0 < event->attendee_list->count) ? 1 : 0,
779 (0 < event->exception_list->count) ? 1 : 0,
780 (0 < event->extended_list->count) ? 1 : 0,
781 event->freq, is_allday);
783 ret = cal_db_util_query_prepare(query, &stmt);
784 if (CALENDAR_ERROR_NONE != ret) {
785 /* LCOV_EXCL_START */
786 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
787 SECURE("query[%s]", query);
795 cal_db_util_stmt_bind_text(stmt, index, event->summary);
798 if (event->description)
799 cal_db_util_stmt_bind_text(stmt, index, event->description);
803 cal_db_util_stmt_bind_text(stmt, index, event->location);
806 if (event->categories)
807 cal_db_util_stmt_bind_text(stmt, index, event->categories);
811 cal_db_util_stmt_bind_text(stmt, index, event->exdate);
815 cal_db_util_stmt_bind_text(stmt, index, event->uid);
818 if (event->organizer_name)
819 cal_db_util_stmt_bind_text(stmt, index, event->organizer_name);
822 if (event->organizer_email)
823 cal_db_util_stmt_bind_text(stmt, index, event->organizer_email);
826 if (CALENDAR_TIME_LOCALTIME == event->start.type) {
827 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME,
828 event->start.time.date.year,
829 event->start.time.date.month,
830 event->start.time.date.mday,
831 event->start.time.date.hour,
832 event->start.time.date.minute,
833 event->start.time.date.second);
834 cal_db_util_stmt_bind_text(stmt, index, dtstart_datetime);
838 if (event->start_tzid)
839 cal_db_util_stmt_bind_text(stmt, index, event->start_tzid);
842 if (CALENDAR_TIME_LOCALTIME == event->end.type) {
843 snprintf(dtend_datetime, sizeof(dtend_datetime), CAL_FORMAT_LOCAL_DATETIME,
844 event->end.time.date.year,
845 event->end.time.date.month,
846 event->end.time.date.mday,
847 event->end.time.date.hour,
848 event->end.time.date.minute,
849 event->end.time.date.second);
850 cal_db_util_stmt_bind_text(stmt, index, dtend_datetime);
855 cal_db_util_stmt_bind_text(stmt, index, event->end_tzid);
858 if (event->recurrence_id)
859 cal_db_util_stmt_bind_text(stmt, index, event->recurrence_id);
863 cal_db_util_stmt_bind_text(stmt, index, event->rdate);
866 if (event->sync_data1)
867 cal_db_util_stmt_bind_text(stmt, index, event->sync_data1);
870 if (event->sync_data2)
871 cal_db_util_stmt_bind_text(stmt, index, event->sync_data2);
874 if (event->sync_data3)
875 cal_db_util_stmt_bind_text(stmt, index, event->sync_data3);
878 if (event->sync_data4)
879 cal_db_util_stmt_bind_text(stmt, index, event->sync_data4);
882 ret = cal_db_util_stmt_step(stmt);
883 sqlite3_finalize(stmt);
884 if (CALENDAR_ERROR_NONE != ret) {
885 /* LCOV_EXCL_START */
886 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
890 event_id = cal_db_util_last_insert_id();
893 * update parent event changed ver in case this event is exception mod
894 * which is original_event_id > 0
896 cal_db_event_update_original_event_version(original_event_id, input_ver);
898 calendar_record_get_int(record, _calendar_event.id, &tmp);
899 cal_record_set_int(record, _calendar_event.id, event_id);
903 cal_db_rrule_get_rrule_from_record(record, &rrule);
905 cal_db_rrule_insert_record(event_id, rrule);
909 if (0 < original_event_id)
910 cal_record_set_int(record, _calendar_event.original_event_id, original_event_id);
912 cal_db_instance_publish_record(record);
914 while (event->uid && *event->uid) {
915 if (NULL == event->recurrence_id || '\0' == *event->recurrence_id) {
916 DBG("this is parent");
918 * parent exception event is inserted in case child exception existed already.
919 * find child exceptions and link(one exception) or devide(this and future/prior)
923 list = cal_db_event_get_list_with_uid(event->uid, event_id);
926 GList *l = g_list_first(list);
928 int child_id = GPOINTER_TO_INT(l->data);
929 /* update children original_event_id */
930 cal_db_event_update_child_origina_event_id(child_id, event_id);
931 char *recurrence_id = NULL;
932 recurrence_id = cal_db_event_get_recurrence_id_from_exception(child_id);
933 if (NULL == recurrence_id || '\0' == *recurrence_id) {
934 if (recurrence_id) free(recurrence_id);
938 /* remove parent instance */
939 cal_db_event_apply_recurrence_id(event_id, event, recurrence_id, child_id);
945 DBG("this is child");
946 /* get parent with uid and update original_event_id */
948 parent_id = __get_parent_id_with_uid(event->uid, event_id);
950 /* LCOV_EXCL_START */
951 ERR("__get_parent_id_with_uid() Fail");
955 calendar_record_h parent = NULL;
956 cal_db_get_record(_calendar_event._uri, parent_id, &parent);
957 cal_db_event_apply_recurrence_id(parent_id, (cal_event_s *)parent, event->recurrence_id, event_id);
958 calendar_record_destroy(parent, true);
963 if (event->alarm_list->count) {
965 ret = cal_db_alarm_insert_records(event->alarm_list, event_id);
966 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_alarm_insert_records() Fail(%d)", ret);
971 if (0 < event->attendee_list->count) {
972 DBG("insert attendee");
973 ret = cal_db_attendee_insert_records(event->attendee_list, event_id);
974 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_attendee_insert_records() Fail(%d)", ret);
979 if (original_event_id <= 0 && 0 < event->exception_list->count) {
980 DBG("insert exception");
981 ret = cal_db_event_insert_records(event->exception_list, event_id);
982 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_event_insert_records() Fail(%d)", ret);
987 if (0 < event->extended_list->count) {
988 DBG("insert extended");
989 ret = cal_db_extended_insert_records(event->extended_list, event_id, CALENDAR_RECORD_TYPE_EVENT);
990 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_extended_insert_records() Fail(%d)", ret);
995 cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
997 cal_record_set_int(record, _calendar_event.id, tmp);
998 return CALENDAR_ERROR_NONE;
1001 int cal_db_event_insert_records(cal_list_s *list_s, int original_event_id)
1005 calendar_record_h record = NULL;
1006 calendar_list_h list = (calendar_list_h)list_s;
1008 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
1010 calendar_list_get_count(list, &count);
1012 return CALENDAR_ERROR_NONE;
1014 calendar_list_first(list);
1015 while (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(list, &record)) {
1016 ret = cal_db_event_insert_record(record, original_event_id, NULL);
1017 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_extended_insert_record() Fail(%d)", ret);
1018 calendar_list_next(list);
1020 return CALENDAR_ERROR_NONE;