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) {
68 ERR("cal_db_util_query_exec() Fail(%d)", ret);
69 SECURE("[%s]", query);
73 return CALENDAR_ERROR_NONE;
76 int cal_db_event_check_value_validation(cal_event_s *event)
78 long long int slli = 0;
79 long long int elli = 0;
81 RETV_IF(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
83 if (event->start.type != event->end.type) {
84 ERR("normal end(%lld) < start(%lld)",
85 event->end.time.utime, event->start.time.utime);
86 return CALENDAR_ERROR_INVALID_PARAMETER;
89 switch (event->start.type) {
90 case CALENDAR_TIME_UTIME:
91 if (event->end.time.utime < event->start.time.utime) {
92 ERR("normal end(%lld) < start(%lld) so set same", event->end.time.utime, event->start.time.utime);
93 event->end.time.utime = event->start.time.utime;
94 return CALENDAR_ERROR_INVALID_PARAMETER;
98 case CALENDAR_TIME_LOCALTIME:
99 /* check invalid value */
100 if (event->start.time.date.month < 1 || 12 < event->start.time.date.month) {
101 ERR("Error check start month(input:%d)", event->start.time.date.month);
102 return CALENDAR_ERROR_INVALID_PARAMETER;
103 } else if (event->start.time.date.mday < 1 || 31 < event->start.time.date.mday) {
104 ERR("Error check start mday(input:%d)", event->start.time.date.mday);
105 return CALENDAR_ERROR_INVALID_PARAMETER;
106 } else if (event->end.time.date.month < 1 || 12 < event->end.time.date.month) {
107 ERR("Error check end month(input:%d)", event->end.time.date.month);
108 return CALENDAR_ERROR_INVALID_PARAMETER;
109 } else if (event->end.time.date.mday < 1 || 31 < event->end.time.date.mday) {
110 ERR("Error check end mday(input:%d)", event->end.time.date.mday);
111 return CALENDAR_ERROR_INVALID_PARAMETER;
113 /* handle hour, minute, second */
114 if (event->start.time.date.hour < 0 || 24 < event->start.time.date.hour)
115 event->start.time.date.hour = 0;
116 if (event->start.time.date.minute < 0 || 60 < event->start.time.date.minute)
117 event->start.time.date.minute = 0;
118 if (event->start.time.date.second < 0 || 60 < event->start.time.date.second)
119 event->start.time.date.second = 0;
120 if (event->end.time.date.hour < 0 || 24 < event->end.time.date.hour)
121 event->end.time.date.hour = 0;
122 if (event->end.time.date.minute < 0 || 60 < event->end.time.date.minute)
123 event->end.time.date.minute = 0;
124 if (event->end.time.date.second < 0 || 60 < event->end.time.date.second)
125 event->end.time.date.second = 0;
128 /* check end < start; convert long long int */
129 slli = cal_time_convert_itol(NULL,
130 event->start.time.date.year, event->start.time.date.month, event->start.time.date.mday,
131 event->start.time.date.hour, event->start.time.date.minute, event->start.time.date.second);
132 elli = cal_time_convert_itol(NULL,
133 event->end.time.date.year, event->end.time.date.month, event->end.time.date.mday,
134 event->end.time.date.hour, event->end.time.date.minute, event->end.time.date.second);
136 if (1 < slli - elli) {
137 /* 1 is to ignore milliseconds */
138 ERR("allday end(%lld) < start(%lld) so set same", elli, slli);
139 return CALENDAR_ERROR_INVALID_PARAMETER;
144 return CALENDAR_ERROR_NONE;
147 GList* cal_db_event_get_list_with_uid(char *uid, int parent_id)
150 RETV_IF(NULL == uid, NULL);
151 RETV_IF('\0' == *uid, NULL);
153 char query[CAL_DB_SQL_MAX_LEN] = {0};
154 snprintf(query, sizeof(query), "SELECT id FROM %s WHERE original_event_id=-1 AND uid LIKE '%s' AND id!=%d",
155 CAL_TABLE_SCHEDULE, uid, parent_id);
157 sqlite3_stmt *stmt = NULL;
158 ret = cal_db_util_query_prepare(query, &stmt);
159 if (CALENDAR_ERROR_NONE != ret) {
160 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
161 SECURE("query[%s]", query);
166 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
167 int id = sqlite3_column_int(stmt, 0);
168 l = g_list_append(l, GINT_TO_POINTER(id));
170 sqlite3_finalize(stmt);
174 void cal_db_event_update_child_origina_event_id(int child_id, int parent_id)
179 char query[CAL_DB_SQL_MAX_LEN] = {0};
180 snprintf(query, sizeof(query), "UPDATE %s SET original_event_id=%d WHERE id=%d",
181 CAL_TABLE_SCHEDULE, parent_id, child_id);
182 ret = cal_db_util_query_exec(query);
183 if (CALENDAR_ERROR_NONE != ret) {
184 ERR("cal_db_util_query_exec() Fail(%d)", ret);
185 SECURE("[%s]", query);
189 char* cal_db_event_get_recurrence_id_from_exception(int child_id)
192 char query[CAL_DB_SQL_MAX_LEN] = {0};
193 snprintf(query, sizeof(query), "SELECT recurrence_id FROM %s WHERE id=%d",
194 CAL_TABLE_SCHEDULE, child_id);
196 sqlite3_stmt *stmt = NULL;
197 ret = cal_db_util_query_prepare(query, &stmt);
198 if (CALENDAR_ERROR_NONE != ret) {
199 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
200 SECURE("query[%s]", query);
204 char *recurrence_id = NULL;
205 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
206 recurrence_id = cal_strdup((const char*)sqlite3_column_text(stmt, 0));
208 sqlite3_finalize(stmt);
209 return recurrence_id;
212 static void __get_tzid_and_range(char *p, char **out_tzid, int *out_range)
216 RET_IF(NULL == out_tzid);
217 RET_IF(NULL == out_range);
220 s = g_strsplit(p, ";", -1);
221 RETM_IF(NULL == s, "g_strsplit() Fail");
223 int count = g_strv_length(s);
226 int range = CAL_RECURRENCE_ID_RANGE_NONE;
227 for (i = 0; i < count; i++) {
228 if (NULL == s[i] || '\0' == *s[i])
231 if (CAL_STRING_EQUAL == strncmp(s[i], "TZID=", strlen("TZID="))) {
234 tzid = strdup(s[i] + strlen("TZID="));
235 DBG("tzid [%s]", tzid);
236 } else if (CAL_STRING_EQUAL == strncmp(s[i], "RANGE=", strlen("RANGE="))) {
237 char *param = s[i] + strlen("RANGE=");
238 if (CAL_STRING_EQUAL == strncmp(param, "THISANDFUTURE", strlen("THISANDFUTURE")))
239 range = CAL_RECURRENCE_ID_RANGE_THISANDFUTURE;
240 else if (CAL_STRING_EQUAL == strncmp(param, "THISANDPRIOR", strlen("THISANDPRIOR")))
241 range = CAL_RECURRENCE_ID_RANGE_THISANDPRIOR;
243 ERR("Invalid param[%s]", s[i]);
245 ERR("Invalid param[%s]", s[i]);
253 static void cal_db_event_apply_recurrence_id_child(int child_id, cal_event_s *event, calendar_time_s until, bool is_prior)
256 calendar_record_h record = NULL;
257 ret = cal_db_get_record(_calendar_event._uri, child_id, &record);
258 RETM_IF(CALENDAR_ERROR_NONE != ret, "cal_db_get_record() Fail(%d)", ret);
260 if (true == is_prior) {
261 cal_record_set_caltime(record, _calendar_event.start_time, event->start);
262 cal_record_set_caltime(record, _calendar_event.end_time, event->end);
263 switch (event->start.type) {
264 case CALENDAR_TIME_UTIME:
265 DBG("dtstart(%lld) dtend(%lld)", event->start.time.utime, event->end.time.utime);
267 case CALENDAR_TIME_LOCALTIME:
268 DBG("dtstart(%04d-%02d-%02dT%02d:%02d:%02d) dtend(%04d-%02d-%02dT%02d:%02d:%02d)",
269 event->start.time.date.year, event->start.time.date.month, event->start.time.date.mday,
270 event->start.time.date.hour, event->start.time.date.minute, event->start.time.date.second,
271 event->end.time.date.year, event->end.time.date.month, event->end.time.date.mday,
272 event->end.time.date.hour, event->end.time.date.minute, event->end.time.date.second);
277 cal_record_set_int(record, _calendar_event.freq, event->freq);
278 cal_record_set_int(record, _calendar_event.interval, event->interval);
279 cal_record_set_int(record, _calendar_event.wkst, event->wkst);
280 if (event->byyearday && *event->byyearday)
281 cal_record_set_str(record, _calendar_event.byyearday, event->byyearday);
282 if (event->byweekno && *event->byweekno)
283 cal_record_set_str(record, _calendar_event.byweekno, event->byweekno);
284 if (event->bymonth && *event->bymonth)
285 cal_record_set_str(record, _calendar_event.bymonth, event->bymonth);
286 if (event->bymonthday && *event->bymonthday)
287 cal_record_set_str(record, _calendar_event.bymonthday, event->bymonthday);
288 if (event->byday && *event->byday)
289 cal_record_set_str(record, _calendar_event.byday, event->byday);
290 if (event->bysetpos && *event->bysetpos)
291 cal_record_set_str(record, _calendar_event.bysetpos, event->bysetpos);
294 cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
295 cal_record_set_caltime(record, _calendar_event.until_time, until);
298 cal_record_set_str(record, _calendar_event.uid, "");
299 cal_record_set_int(record, _calendar_event.original_event_id, -1);
301 cal_db_update_record(record);
302 calendar_record_destroy(record, true);
304 static void __get_next_instance_caltime(int parent_id, calendar_time_s *caltime, calendar_time_s *dtstart, calendar_time_s *dtend)
307 char query[CAL_DB_SQL_MAX_LEN] = {0};
308 sqlite3_stmt *stmt = NULL;
310 switch (caltime->type) {
311 case CALENDAR_TIME_UTIME:
312 snprintf(query, sizeof(query), "SELECT dtstart_utime, dtend_utime FROM %s WHERE event_id=%d AND dtstart_utime>%lld "
313 "ORDER BY dtstart_utime ASC LIMIT 1",
314 CAL_TABLE_NORMAL_INSTANCE, parent_id, caltime->time.utime);
316 ret = cal_db_util_query_prepare(query, &stmt);
317 if (CALENDAR_ERROR_NONE != ret) {
318 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
319 SECURE("query[%s]", query);
323 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
324 dtstart->type = CALENDAR_TIME_UTIME;
325 dtstart->time.utime = sqlite3_column_int64(stmt, 0);
326 dtend->type = CALENDAR_TIME_UTIME;
327 dtend->time.utime = sqlite3_column_int64(stmt, 0);
331 case CALENDAR_TIME_LOCALTIME:
332 snprintf(query, sizeof(query), "SELECT dtstart_datetime, dtend_datetime FROM %s "
333 "WHERE event_id=%d AND dtstart_datetime>'%04d-%02d-%02dT%02d:%02d:%02d' "
334 "ORDER BY dtstart_datetime ASC LIMIT 1",
335 CAL_TABLE_ALLDAY_INSTANCE, parent_id,
336 caltime->time.date.year, caltime->time.date.month, caltime->time.date.mday,
337 caltime->time.date.hour, caltime->time.date.minute, caltime->time.date.second);
339 ret = cal_db_util_query_prepare(query, &stmt);
340 if (CALENDAR_ERROR_NONE != ret) {
341 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
342 SECURE("query[%s]", query);
346 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
348 dtstart->type = CALENDAR_TIME_LOCALTIME;
349 temp = (char *)sqlite3_column_text(stmt, 0);
351 sscanf(temp, CAL_FORMAT_LOCAL_DATETIME,
352 &(dtstart->time.date.year), &(dtstart->time.date.month), &(dtstart->time.date.mday),
353 &(dtstart->time.date.hour), &(dtstart->time.date.minute), &(dtstart->time.date.second));
355 dtend->type = CALENDAR_TIME_LOCALTIME;
356 temp = (char *)sqlite3_column_text(stmt, 1);
358 sscanf(temp, CAL_FORMAT_LOCAL_DATETIME,
359 &(dtend->time.date.year), &(dtend->time.date.month), &(dtend->time.date.mday),
360 &(dtend->time.date.hour), &(dtend->time.date.minute), &(dtend->time.date.second));
365 sqlite3_finalize(stmt);
367 static void __get_last_instance_caltime(int parent_id, int type, calendar_time_s *dtstart)
370 char query[CAL_DB_SQL_MAX_LEN] = {0};
371 sqlite3_stmt *stmt = NULL;
374 case CALENDAR_TIME_UTIME:
375 snprintf(query, sizeof(query), "SELECT dtstart_utime FROM %s WHERE event_id=%d "
376 "ORDER BY dtstart_utime DESC LIMIT 1",
377 CAL_TABLE_NORMAL_INSTANCE, parent_id);
378 ret = cal_db_util_query_prepare(query, &stmt);
379 if (CALENDAR_ERROR_NONE != ret) {
380 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
381 SECURE("query[%s]", query);
384 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
385 dtstart->type = CALENDAR_TIME_UTIME;
386 dtstart->time.utime = sqlite3_column_int64(stmt, 0);
390 case CALENDAR_TIME_LOCALTIME:
391 snprintf(query, sizeof(query), "SELECT dtstart_datetime FROM %s WHERE event_id=%d "
392 "ORDER BY dtstart_datetime DESC LIMIT 1",
393 CAL_TABLE_ALLDAY_INSTANCE, parent_id);
394 ret = cal_db_util_query_prepare(query, &stmt);
395 if (CALENDAR_ERROR_NONE != ret) {
396 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
397 SECURE("query[%s]", query);
400 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
402 dtstart->type = CALENDAR_TIME_LOCALTIME;
403 temp = (char *)sqlite3_column_text(stmt, 0);
405 sscanf(temp, CAL_FORMAT_LOCAL_DATETIME,
406 &(dtstart->time.date.year), &(dtstart->time.date.month), &(dtstart->time.date.mday),
407 &(dtstart->time.date.hour), &(dtstart->time.date.minute), &(dtstart->time.date.second));
409 ERR("datetime is NULL");
414 sqlite3_finalize(stmt);
417 static void __del_recurence_id_instance(calendar_time_s *rectime, int parent_id)
420 char query[CAL_DB_SQL_MAX_LEN] = {0};
421 switch (rectime->type) {
422 case CALENDAR_TIME_UTIME:
423 snprintf(query, sizeof(query), "DELETE FROM %s WHERE dtstart_utime=%lld AND event_id=%d",
424 CAL_TABLE_NORMAL_INSTANCE, rectime->time.utime, parent_id);
426 case CALENDAR_TIME_LOCALTIME:
427 snprintf(query, sizeof(query), "DELETE FROM %s WHERE dtstart_datetime='%04d-%02d-%02dT%02d:%02d:%02d' AND event_id=%d",
428 CAL_TABLE_ALLDAY_INSTANCE, rectime->time.date.year, rectime->time.date.month, rectime->time.date.mday,
429 rectime->time.date.hour, rectime->time.date.minute, rectime->time.date.second, parent_id);
432 ret = cal_db_util_query_exec(query);
433 if (CALENDAR_ERROR_NONE != ret) {
434 ERR("cal_db_util_query_exec() Fail(%d)", ret);
435 SECURE("[%s]", query);
439 int y = 0, m = 0, d = 0;
440 int h = 0, n = 0, s = 0;
441 switch (rectime->type) {
442 case CALENDAR_TIME_UTIME:
443 cal_time_get_datetime(rectime->time.utime, &y, &m, &d, &h, &n, &s);
444 DBG("[DELETED] %04d-%02d-%02dT%02d:%02d:%02d (utime)", y, m, d, h, n, s);
446 case CALENDAR_TIME_LOCALTIME:
447 DBG("[DELETED] %04d-%02d-%02dT%02d:%02d:%02d (local)",
448 rectime->time.date.year, rectime->time.date.month, rectime->time.date.mday,
449 rectime->time.date.hour, rectime->time.date.minute, rectime->time.date.second);
454 static void __set_original_event_id_in_child(int child_id, int parent_id)
457 char query[CAL_DB_SQL_MAX_LEN] = {0};
458 snprintf(query, sizeof(query), "UPDATE %s SET original_event_id=%d WHERE id=%d",
459 CAL_TABLE_SCHEDULE, parent_id, child_id);
461 ret = cal_db_util_query_exec(query);
462 if (CALENDAR_ERROR_NONE != ret) {
463 ERR("cal_db_util_query_exec() Fail(%d)", ret);
464 SECURE("[%s]", query);
469 * RECURRENCE-ID;VALUE=DATE:19960401
470 * RECURRENCE-ID;RANGE=THISANDFUTURE:19960120T120000Z
471 * RECURRENCE-ID;RANGE=THISANDPRIOR:19980401T133000Z
472 * RECURRENCE-ID;TZID=Asia/Seoul:20150106T090000
474 void cal_db_event_apply_recurrence_id(int parent_id, cal_event_s *event, char *recurrence_id, int child_id)
478 RET_IF(NULL == recurrence_id);
479 RET_IF('\0' == *recurrence_id);
482 t = g_strsplit(recurrence_id, ":", -1);
483 RETM_IF(NULL == t, "g_strsplit() Fail");
485 if ('\0' == *t[0]) { /* no param */
489 int count = g_strv_length(t);
490 int len_param = strlen(t[count -1]);
491 *(recurrence_id + strlen(recurrence_id) - len_param -1) = '\0';
494 char *datetime = recurrence_id + strlen(recurrence_id) +1;
495 int len_datetime = strlen(datetime);
496 DBG("datetime[%s]", datetime);
499 int range = CAL_RECURRENCE_ID_RANGE_NONE;
500 __get_tzid_and_range(recurrence_id, &tzid, &range);
502 int y = 0, m = 0, d = 0;
503 int h = 0, n = 0, s = 0;
504 char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
505 long long int dtstart_utime = 0;
506 calendar_time_s rectime = {0};
507 switch (len_datetime) {
509 sscanf(datetime, CAL_DATETIME_FORMAT_YYYYMMDD, &y, &m, &d);
510 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME, y, m, d, 0, 0, 0);
511 rectime.type = CALENDAR_TIME_LOCALTIME;
512 rectime.time.date.year = y;
513 rectime.time.date.month = m;
514 rectime.time.date.mday = d;
515 rectime.time.date.hour = 0;
516 rectime.time.date.minute = 0;
517 rectime.time.date.second = 0;
520 sscanf(datetime, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS, &y, &m, &d, &h, &n, &s);
522 dtstart_utime = cal_time_convert_itol(tzid, y, m, d, h, n, s);
523 rectime.type = CALENDAR_TIME_UTIME;
524 rectime.time.utime = dtstart_utime;
526 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME, y, m, d, h, n, s);
527 rectime.type = CALENDAR_TIME_LOCALTIME;
528 rectime.time.date.year = y;
529 rectime.time.date.month = m;
530 rectime.time.date.mday = d;
531 rectime.time.date.hour = h;
532 rectime.time.date.minute = n;
533 rectime.time.date.second = s;
537 sscanf(datetime, CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, &y, &m, &d, &h, &n, &s);
538 dtstart_utime = cal_time_convert_itol(tzid, y, m, d, h, n, s);
539 rectime.type = CALENDAR_TIME_UTIME;
540 rectime.time.utime = dtstart_utime;
545 calendar_time_s until = {0};
546 calendar_time_s dtstart = {0};
547 calendar_time_s dtend = {0};
548 calendar_record_h record = (calendar_record_h)event;
550 case CAL_RECURRENCE_ID_RANGE_THISANDFUTURE:
552 switch (event->range_type) {
553 case CALENDAR_RANGE_UNTIL:
554 case CALENDAR_RANGE_NONE:
555 until = event->start;
557 case CALENDAR_RANGE_COUNT:
558 __get_last_instance_caltime(parent_id, rectime.type, &until);
561 cal_db_event_apply_recurrence_id_child(child_id, event, until, false);
563 DBG("update parent");
565 cal_time_modify_caltime(&until, -1);
566 cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
567 cal_record_set_caltime(record, _calendar_event.until_time, until);
568 cal_record_set_str(record, _calendar_event.recurrence_id, "");
569 cal_record_set_str(record, _calendar_event.uid, "");
570 cal_db_update_record(record);
572 case CAL_RECURRENCE_ID_RANGE_THISANDPRIOR:
575 cal_db_event_apply_recurrence_id_child(child_id, event, until, true);
577 DBG("update parent");
578 __get_next_instance_caltime(parent_id, &until, &dtstart, &dtend);
579 cal_record_set_caltime(record, _calendar_event.start_time, dtstart);
580 cal_record_set_caltime(record, _calendar_event.end_time, dtend);
581 switch (event->range_type) {
582 case CALENDAR_RANGE_UNTIL:
583 case CALENDAR_RANGE_NONE:
585 case CALENDAR_RANGE_COUNT:
586 __get_last_instance_caltime(parent_id, rectime.type, &until);
587 cal_record_set_int(record, _calendar_event.range_type, CALENDAR_RANGE_UNTIL);
588 cal_record_set_caltime(record, _calendar_event.until_time, until);
589 DBG(CAL_FORMAT_LOCAL_DATETIME,
590 until.time.date.year, until.time.date.month, until.time.date.mday,
591 until.time.date.hour, until.time.date.minute, until.time.date.second);
594 cal_record_set_str(record, _calendar_event.recurrence_id, "");
595 cal_db_update_record(record);
598 __del_recurence_id_instance(&rectime, parent_id);
599 __set_original_event_id_in_child(child_id, parent_id);
603 static int __get_parent_id_with_uid(char *uid, int child_id)
606 char query[CAL_DB_SQL_MAX_LEN] = {0};
608 snprintf(query, sizeof(query), "SELECT id FROM %s WHERE original_event_id=-1 AND id!=%d AND uid='%s'",
609 CAL_TABLE_SCHEDULE, child_id, uid);
611 sqlite3_stmt *stmt = NULL;
612 ret = cal_db_util_query_prepare(query, &stmt);
613 if (CALENDAR_ERROR_NONE != ret) {
614 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
615 SECURE("query[%s]", query);
618 if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt))
619 parent_id = sqlite3_column_int64(stmt, 0);
621 sqlite3_finalize(stmt);
622 DBG("found parent_id(%d)", parent_id);
626 int cal_db_event_insert_record(calendar_record_h record, int original_event_id, int *id)
632 char query[CAL_DB_SQL_MAX_LEN] = {0};
633 char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
634 char dtend_datetime[CAL_STR_SHORT_LEN32] = {0};
635 sqlite3_stmt *stmt = NULL;
636 cal_event_s* event = (cal_event_s*)(record);
637 cal_rrule_s *rrule = NULL;
639 int calendar_book_id = 0;
640 calendar_record_h record_calendar = NULL;
644 RETV_IF(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
646 ret = cal_db_event_check_value_validation(event);
647 if (CALENDAR_ERROR_NONE != ret) {
648 ERR("cal_db_event_check_value_validation() Fail(%d)", ret);
653 if (cal_access_control_have_write_permission(event->calendar_id) == false) {
654 ERR("cal_access_control_have_write_permission() Fail");
655 return CALENDAR_ERROR_PERMISSION_DENIED;
658 ret = calendar_record_get_int(record, _calendar_event.calendar_book_id, &calendar_book_id);
659 DBG("calendar_book_id(%d)", calendar_book_id);
661 ret = cal_db_get_record(_calendar_book._uri, calendar_book_id, &record_calendar);
662 RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "cal_db_get_record() Fail(%d)", ret);
664 calendar_record_destroy(record_calendar, true);
666 has_alarm = cal_db_alarm_has_alarm(event->alarm_list);
667 cal_db_timezone_search_with_tzid(event->calendar_id, event->start_tzid, &timezone_id);
668 input_ver = cal_db_util_get_next_ver();
671 if (CALENDAR_TIME_LOCALTIME == event->start.type
672 && (0 == event->start.time.date.hour)
673 && (0 == event->start.time.date.minute)
674 && (0 == event->start.time.date.second)
675 && (0 == event->end.time.date.hour)
676 && (0 == event->end.time.date.minute)
677 && (0 == event->end.time.date.second)) {
681 snprintf(query, sizeof(query), "INSERT INTO %s ("
683 "created_ver, changed_ver, "
684 "summary, description, location, categories, exdate, "
685 "task_status, priority, "
687 "contact_id, busy_status, sensitivity, uid, "
688 "organizer_name, organizer_email, meeting_status, "
690 "original_event_id, "
691 "latitude, longitude, "
693 "created_time, completed_time, progress, "
694 "dtstart_type, dtstart_utime, dtstart_datetime, dtstart_tzid, "
695 "dtend_type, dtend_utime, dtend_datetime, dtend_tzid, "
696 "last_mod, rrule_id, "
697 "recurrence_id, rdate, has_attendee, "
698 "has_alarm, system_type, updated, "
699 "sync_data1, sync_data2, sync_data3, sync_data4,"
700 "has_exception, has_extended, freq, is_allday "
713 "strftime('%%s', 'now'), %lld, %d, "
716 "strftime('%%s', 'now'), %d, "
717 "?, ?, %d, %d, %d, %d, "
721 CAL_SCH_TYPE_EVENT, /*event->cal_type,*/
722 input_ver, input_ver,
723 event->event_status, event->priority,
724 event->timezone ? event->timezone : timezone_id,
725 event->contact_id, event->busy_status, event->sensitivity,
726 event->meeting_status,
729 event->latitude, event->longitude,
731 (long long int)0, 0, /* event->completed_time, event->progress */
732 event->start.type, event->start.type == CALENDAR_TIME_UTIME ? event->start.time.utime : 0,
733 event->end.type, event->end.type == CALENDAR_TIME_UTIME ? event->end.time.utime : 0,
734 0 < event->freq ? 1 : 0,
735 (0 < event->attendee_list->count) ? 1 : 0,
739 (0 < event->exception_list->count) ? 1 : 0,
740 (0 < event->extended_list->count) ? 1 : 0,
741 event->freq, is_allday);
743 ret = cal_db_util_query_prepare(query, &stmt);
744 if (CALENDAR_ERROR_NONE != ret) {
745 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
746 SECURE("query[%s]", query);
753 cal_db_util_stmt_bind_text(stmt, index, event->summary);
756 if (event->description)
757 cal_db_util_stmt_bind_text(stmt, index, event->description);
761 cal_db_util_stmt_bind_text(stmt, index, event->location);
764 if (event->categories)
765 cal_db_util_stmt_bind_text(stmt, index, event->categories);
769 cal_db_util_stmt_bind_text(stmt, index, event->exdate);
773 cal_db_util_stmt_bind_text(stmt, index, event->uid);
776 if (event->organizer_name)
777 cal_db_util_stmt_bind_text(stmt, index, event->organizer_name);
780 if (event->organizer_email)
781 cal_db_util_stmt_bind_text(stmt, index, event->organizer_email);
784 if (CALENDAR_TIME_LOCALTIME == event->start.type) {
785 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME,
786 event->start.time.date.year,
787 event->start.time.date.month,
788 event->start.time.date.mday,
789 event->start.time.date.hour,
790 event->start.time.date.minute,
791 event->start.time.date.second);
792 cal_db_util_stmt_bind_text(stmt, index, dtstart_datetime);
796 if (event->start_tzid)
797 cal_db_util_stmt_bind_text(stmt, index, event->start_tzid);
800 if (CALENDAR_TIME_LOCALTIME == event->end.type) {
801 snprintf(dtend_datetime, sizeof(dtend_datetime), CAL_FORMAT_LOCAL_DATETIME,
802 event->end.time.date.year,
803 event->end.time.date.month,
804 event->end.time.date.mday,
805 event->end.time.date.hour,
806 event->end.time.date.minute,
807 event->end.time.date.second);
808 cal_db_util_stmt_bind_text(stmt, index, dtend_datetime);
813 cal_db_util_stmt_bind_text(stmt, index, event->end_tzid);
816 if (event->recurrence_id)
817 cal_db_util_stmt_bind_text(stmt, index, event->recurrence_id);
821 cal_db_util_stmt_bind_text(stmt, index, event->rdate);
824 if (event->sync_data1)
825 cal_db_util_stmt_bind_text(stmt, index, event->sync_data1);
828 if (event->sync_data2)
829 cal_db_util_stmt_bind_text(stmt, index, event->sync_data2);
832 if (event->sync_data3)
833 cal_db_util_stmt_bind_text(stmt, index, event->sync_data3);
836 if (event->sync_data4)
837 cal_db_util_stmt_bind_text(stmt, index, event->sync_data4);
840 ret = cal_db_util_stmt_step(stmt);
841 sqlite3_finalize(stmt);
842 if (CALENDAR_ERROR_NONE != ret) {
843 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
846 event_id = cal_db_util_last_insert_id();
849 * update parent event changed ver in case this event is exception mod
850 * which is original_event_id > 0
852 cal_db_event_update_original_event_version(original_event_id, input_ver);
854 calendar_record_get_int(record, _calendar_event.id, &tmp);
855 cal_record_set_int(record, _calendar_event.id, event_id);
859 cal_db_rrule_get_rrule_from_record(record, &rrule);
861 cal_db_rrule_insert_record(event_id, rrule);
865 if (0 < original_event_id)
866 cal_record_set_int(record, _calendar_event.original_event_id, original_event_id);
868 cal_db_instance_publish_record(record);
870 while (event->uid && *event->uid) {
871 if (NULL == event->recurrence_id || '\0' == *event->recurrence_id) {
872 DBG("this is parent");
874 * parent exception event is inserted in case child exception existed already.
875 * find child exceptions and link(one exception) or devide(this and future/prior)
879 list = cal_db_event_get_list_with_uid(event->uid, event_id);
882 GList *l = g_list_first(list);
884 int child_id = GPOINTER_TO_INT(l->data);
885 /* update children original_event_id */
886 cal_db_event_update_child_origina_event_id(child_id, event_id);
887 char *recurrence_id = NULL;
888 recurrence_id = cal_db_event_get_recurrence_id_from_exception(child_id);
889 if (NULL == recurrence_id || '\0' == *recurrence_id) {
890 if (recurrence_id) free(recurrence_id);
894 /* remove parent instance */
895 cal_db_event_apply_recurrence_id(event_id, event, recurrence_id, child_id);
901 DBG("this is child");
902 /* get parent with uid and update original_event_id */
904 parent_id = __get_parent_id_with_uid(event->uid, event_id);
906 ERR("__get_parent_id_with_uid() Fail");
909 calendar_record_h parent = NULL;
910 cal_db_get_record(_calendar_event._uri, parent_id, &parent);
911 cal_db_event_apply_recurrence_id(parent_id, (cal_event_s *)parent, event->recurrence_id, event_id);
912 calendar_record_destroy(parent, true);
917 if (event->alarm_list->count) {
919 ret = cal_db_alarm_insert_records(event->alarm_list, event_id);
920 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_alarm_insert_records() Fail(%d)", ret);
925 if (0 < event->attendee_list->count) {
926 DBG("insert attendee");
927 ret = cal_db_attendee_insert_records(event->attendee_list, event_id);
928 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_attendee_insert_records() Fail(%d)", ret);
933 if (original_event_id <= 0 && 0 < event->exception_list->count) {
934 DBG("insert exception");
935 ret = cal_db_event_insert_records(event->exception_list, event_id);
936 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_event_insert_records() Fail(%d)", ret);
941 if (0 < event->extended_list->count) {
942 DBG("insert extended");
943 ret = cal_db_extended_insert_records(event->extended_list, event_id, CALENDAR_RECORD_TYPE_EVENT);
944 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_extended_insert_records() Fail(%d)", ret);
949 cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
951 cal_record_set_int(record, _calendar_event.id, tmp);
952 return CALENDAR_ERROR_NONE;
955 int cal_db_event_insert_records(cal_list_s *list_s, int original_event_id)
959 calendar_record_h record = NULL;
960 calendar_list_h list = (calendar_list_h)list_s;
962 RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
964 calendar_list_get_count(list, &count);
966 return CALENDAR_ERROR_NONE;
968 calendar_list_first(list);
969 while (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(list, &record)) {
970 ret = cal_db_event_insert_record(record, original_event_id, NULL);
971 RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_extended_insert_record() Fail(%d)", ret);
972 calendar_list_next(list);
974 return CALENDAR_ERROR_NONE;