remove unused function: replace records in plugin
[platform/core/pim/calendar-service.git] / server / db / cal_db_plugin_event.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <stdlib.h>
21
22 #include "calendar_db.h"
23 #include "cal_internal.h"
24 #include "cal_typedef.h"
25 #include "cal_view.h"
26 #include "cal_time.h"
27 #include "cal_record.h"
28 #include "cal_list.h"
29 #include "cal_db.h"
30 #include "cal_db_util.h"
31 #include "cal_db_rrule.h"
32 #include "cal_db_query.h"
33 #include "cal_db_plugin_alarm_helper.h"
34 #include "cal_db_instance.h"
35 #include "cal_db_plugin_attendee_helper.h"
36 #include "cal_db_plugin_extended_helper.h"
37 #include "cal_db_plugin_event_helper.h"
38 #include "cal_access_control.h"
39 #include "cal_db_plugin_timezone_helper.h"
40 #include "cal_utils.h"
41
42 static int _cal_db_event_insert_record(calendar_record_h record, int* id);
43 static int _cal_db_event_update_record(calendar_record_h record);
44 static int _cal_db_event_delete_record(int id);
45 static int _cal_db_event_replace_record(calendar_record_h record, int id);
46 static int _cal_db_event_delete_records(int ids[], int count);
47 static int _cal_db_event_get_record(int id, calendar_record_h* out_record);
48 static int _cal_db_event_get_all_records(int offset, int limit, calendar_list_h* out_list);
49 static int _cal_db_event_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
50 static int _cal_db_event_get_count(int *out_count);
51 static int _cal_db_event_get_count_with_query(calendar_query_h query, int *out_count);
52 static int _cal_db_event_update_dirty(calendar_record_h record, int is_dirty_in_time);
53 static int __update_record(calendar_record_h record, int is_dirty_in_time);
54
55 /*
56  * static function
57  */
58 static void _cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record, int *exception, int *extended);
59 static void _cal_db_event_get_property_stmt(sqlite3_stmt *stmt, unsigned int property, int *stmt_count, calendar_record_h record);
60 static void _cal_db_event_get_projection_stmt(sqlite3_stmt *stmt, const unsigned int *projection, const int projection_count, calendar_record_h record);
61 static int _cal_db_event_exception_get_records(int original_id, cal_list_s *list);
62 static int _cal_db_event_exception_delete_with_id(int original_id);
63 static int _cal_db_event_exception_get_ids(int original_id, GList **out_list);
64 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);
65 static int _cal_db_event_get_deleted_data(int id, int* calendar_book_id, int* created_ver, int* original_event_id, char** recurrence_id);
66 static int _cal_db_event_exdate_insert_normal(int event_id, const char* original_exdate, const char* exdate, int **exception_id, int *exception_len);
67 static bool _cal_db_event_check_calendar_book_type(calendar_record_h record);
68
69 static void __check_list(calendar_list_h l)
70 {
71         DBG("---------------------");
72         calendar_list_first(l);
73         int count = 0;
74         calendar_list_get_count(l, &count);
75         DBG("count(%d)", count);
76
77         int i;
78         for (i = 0; i < count; i++) {
79                 calendar_record_h event = NULL;
80                 calendar_list_get_current_record_p(l, &event);
81                 int id = 0;
82                 calendar_record_get_int(event, _calendar_event.id, &id);
83                 int book_id = 0;
84                 calendar_record_get_int(event, _calendar_event.calendar_book_id, &book_id);
85                 char *summary = NULL;
86                 calendar_record_get_str_p(event, _calendar_event.summary, &summary);
87                 int freq = 0;
88                 calendar_record_get_int(event, _calendar_event.freq, &freq);
89
90                 DBG("id(%d) book_id(%d) summary[%s] freq(%d)", id, book_id, summary, freq);
91                 calendar_list_next(l);
92         }
93 }
94
95 cal_db_plugin_cb_s cal_db_event_plugin_cb = {
96         .is_query_only = false,
97         .insert_record = _cal_db_event_insert_record,
98         .update_record = _cal_db_event_update_record,
99         .delete_record = _cal_db_event_delete_record,
100         .replace_record = _cal_db_event_replace_record,
101         .insert_records = NULL,
102         .update_records = NULL,
103         .delete_records = _cal_db_event_delete_records,
104         .replace_records = NULL,
105         .get_record = _cal_db_event_get_record,
106         .get_all_records = _cal_db_event_get_all_records,
107         .get_records_with_query = _cal_db_event_get_records_with_query,
108         .get_count = _cal_db_event_get_count,
109         .get_count_with_query = _cal_db_event_get_count_with_query
110 };
111
112 static int _cal_db_event_insert_record(calendar_record_h record, int* id)
113 {
114         RETV_IF(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER);
115         RETV_IF(false == _cal_db_event_check_calendar_book_type(record), CALENDAR_ERROR_INVALID_PARAMETER);
116         cal_event_s *event = (cal_event_s *)record;
117         return cal_db_event_insert_record(record, event->original_event_id, id);
118 }
119
120 enum {
121         DIRTY_INIT = -1,
122         DIRTY_IN_OTHER = 0,
123         DIRTY_IN_TIME,
124 };
125
126 static int _cal_db_event_get_record(int id, calendar_record_h* out_record)
127 {
128         char query[CAL_DB_SQL_MAX_LEN];
129         int ret = 0;
130         sqlite3_stmt *stmt = NULL;
131         cal_event_s *event = NULL;
132         cal_rrule_s *rrule = NULL;
133         int exception = 0, extended = 0;
134         calendar_record_h record_calendar;
135         calendar_book_sync_event_type_e sync_event_type = CALENDAR_BOOK_SYNC_EVENT_FOR_ME;
136
137         ret = calendar_record_create(_calendar_event._uri, out_record);
138         if (CALENDAR_ERROR_NONE != ret) {
139                 /* LCOV_EXCL_START */
140                 ERR("calendar_record_create(%d)", ret);
141                 return CALENDAR_ERROR_OUT_OF_MEMORY;
142                 /* LCOV_EXCL_STOP */
143         }
144
145         event = (cal_event_s*)(*out_record);
146
147         snprintf(query, sizeof(query),
148                         "SELECT "CAL_QUERY_SCHEDULE_A_ALL" FROM %s AS A "
149                         "WHERE id = %d AND (type = %d OR type = %d) AND calendar_id IN "
150                         "(select id from %s where deleted = 0)",
151                         CAL_TABLE_SCHEDULE,
152                         id, CALENDAR_BOOK_TYPE_EVENT, CALENDAR_BOOK_TYPE_NONE,
153                         CAL_TABLE_CALENDAR);
154         ret = cal_db_util_query_prepare(query, &stmt);
155         if (CALENDAR_ERROR_NONE != ret) {
156                 /* LCOV_EXCL_START */
157                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
158                 SECURE("query[%s]", query);
159                 calendar_record_destroy(*out_record, true);
160                 *out_record = NULL;
161                 return ret;
162                 /* LCOV_EXCL_STOP */
163         }
164
165         ret = cal_db_util_stmt_step(stmt);
166         if (CAL_SQLITE_ROW != ret) {
167                 /* LCOV_EXCL_START */
168                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
169                 SECURE("[%s]", query);
170                 sqlite3_finalize(stmt);
171                 calendar_record_destroy(*out_record, true);
172                 *out_record = NULL;
173                 if (CALENDAR_ERROR_NONE == ret)
174                         return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
175                 return ret;
176                 /* LCOV_EXCL_STOP */
177         }
178
179         _cal_db_event_get_stmt(stmt, false, *out_record, &exception, &extended);
180         sqlite3_finalize(stmt);
181         stmt = NULL;
182
183         /* check */
184         ret = cal_db_get_record(_calendar_book._uri, event->calendar_id, &record_calendar);
185         if (CALENDAR_ERROR_NONE == ret) {
186                 ret = calendar_record_get_int(record_calendar,
187                                 _calendar_book.sync_event, (int *)&sync_event_type);
188                 calendar_record_destroy(record_calendar, true);
189         }
190         if (event->is_deleted == 1 && CALENDAR_BOOK_SYNC_EVENT_FOR_EVERY_AND_REMAIN != sync_event_type) {
191                 /* LCOV_EXCL_START */
192                 calendar_record_destroy(*out_record, true);
193                 *out_record = NULL;
194                 return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
195                 /* LCOV_EXCL_STOP */
196         }
197         if (CALENDAR_RECURRENCE_NONE != event->freq) {
198                 ret = cal_db_rrule_get_rrule(event->index, &rrule);
199                 if (CALENDAR_ERROR_NONE == ret) {
200                         cal_db_rrule_set_rrule_to_record(rrule, *out_record);
201                         CAL_FREE(rrule);
202                 }
203         }
204
205         if (event->has_alarm == 1)
206                 cal_db_alarm_get_records(event->index, event->alarm_list);
207
208         if (event->has_attendee == 1)
209                 cal_db_attendee_get_records(event->index, event->attendee_list);
210
211         if (exception == 1)
212                 _cal_db_event_exception_get_records(event->index, event->exception_list);
213
214         if (extended == 1)
215                 cal_db_extended_get_records(event->index, CALENDAR_RECORD_TYPE_EVENT, event->extended_list);
216
217         return CALENDAR_ERROR_NONE;
218 }
219
220 static int __is_dirty_in_time(calendar_record_h record)
221 {
222         cal_record_s *rec = (cal_record_s *)record;
223         RETV_IF(NULL == record, false);
224         RETV_IF(NULL == rec->view_uri, false);
225
226         int count = 0;
227         const cal_property_info_s *info = cal_view_get_property_info(rec->view_uri, &count);
228         RETVM_IF(NULL == info, false, "cal_view_get_property_info() Fail");
229
230         int i;
231         int is_dirty_in_time = DIRTY_IN_OTHER;
232         for (i = 0; i < count; i++) {
233                 if (false == cal_record_check_property_flag(record, info[i].property_id, CAL_PROPERTY_FLAG_DIRTY))
234                         continue;
235
236                 switch (info[i].property_id) {
237                 case CAL_PROPERTY_EVENT_START:
238                 case CAL_PROPERTY_EVENT_END:
239                 case CAL_PROPERTY_EVENT_START_TZID:
240                 case CAL_PROPERTY_EVENT_END_TZID:
241                 case CAL_PROPERTY_EVENT_FREQ:
242                 case CAL_PROPERTY_EVENT_RANGE_TYPE:
243                 case CAL_PROPERTY_EVENT_UNTIL:
244                 case CAL_PROPERTY_EVENT_COUNT:
245                 case CAL_PROPERTY_EVENT_INTERVAL:
246                 case CAL_PROPERTY_EVENT_BYSECOND:
247                 case CAL_PROPERTY_EVENT_BYMINUTE:
248                 case CAL_PROPERTY_EVENT_BYHOUR:
249                 case CAL_PROPERTY_EVENT_BYDAY:
250                 case CAL_PROPERTY_EVENT_BYMONTHDAY:
251                 case CAL_PROPERTY_EVENT_BYYEARDAY:
252                 case CAL_PROPERTY_EVENT_BYWEEKNO:
253                 case CAL_PROPERTY_EVENT_BYMONTH:
254                 case CAL_PROPERTY_EVENT_BYSETPOS:
255                 case CAL_PROPERTY_EVENT_WKST:
256
257                         is_dirty_in_time = DIRTY_IN_TIME;
258                         break;
259                 }
260                 if (DIRTY_IN_OTHER != is_dirty_in_time) break;
261         }
262         DBG("%sirty in time", DIRTY_IN_OTHER == is_dirty_in_time ? "Not d" : "D");
263         return is_dirty_in_time;
264 }
265
266 time_t __get_time_diff(char *old_tzid, calendar_time_s *old, char *new_tzid, calendar_time_s *new)
267 {
268         RETV_IF(NULL == old, CALENDAR_ERROR_INVALID_PARAMETER);
269         RETV_IF(NULL == new, CALENDAR_ERROR_INVALID_PARAMETER);
270
271         time_t diff = 0;
272         switch (old->type) {
273         case CALENDAR_TIME_UTIME:
274                 switch (new->type) {
275                 case CALENDAR_TIME_UTIME:
276                         DBG("%lld - %lld", old->time.utime, new->time.utime);
277                         diff = old->time.utime - new->time.utime;
278                         break;
279                 case CALENDAR_TIME_LOCALTIME:
280                         DBG("type is changed(%d) -> (%d)", old->type, new->type);
281                         diff = old->time.utime - cal_time_convert_itol(new_tzid,
282                                         new->time.date.year, new->time.date.month, new->time.date.mday,
283                                         new->time.date.hour, new->time.date.minute, new->time.date.second);
284                         break;
285                 }
286                 break;
287         case CALENDAR_TIME_LOCALTIME:
288                 switch (new->type) {
289                 case CALENDAR_TIME_UTIME:
290                         DBG("type is changed(%d) -> (%d)", old->type, new->type);
291                         diff = cal_time_convert_itol(old_tzid,
292                                         old->time.date.year, old->time.date.month, old->time.date.mday,
293                                         old->time.date.hour, old->time.date.minute, old->time.date.second) - new->time.utime;
294                         break;
295                 case CALENDAR_TIME_LOCALTIME:
296                         diff = cal_time_convert_itol(old_tzid,
297                                         old->time.date.year, old->time.date.month, old->time.date.mday,
298                                         old->time.date.hour, old->time.date.minute, old->time.date.second)
299                                 - cal_time_convert_itol(new_tzid, new->time.date.year, new->time.date.month, new->time.date.mday,
300                                                 new->time.date.hour, new->time.date.minute, new->time.date.second);
301                         break;
302                 }
303                 break;
304         }
305         DBG("-------------time diff(%ld)", diff);
306         return diff;
307 }
308
309 static int __get_time_shifted_field(char *old_field, int old_type, int new_type, time_t time_diff, char **new_field)
310 {
311         if (NULL == old_field || '\0' == *old_field)
312                 return CALENDAR_ERROR_NONE;
313
314         gchar **t = NULL;
315         t = g_strsplit_set(old_field, " ,", -1);
316         RETVM_IF(NULL == t, CALENDAR_ERROR_DB_FAILED, "g_strsplit_set() Fail");
317
318         int len_t = g_strv_length(t);
319
320         char *field = NULL;
321         int len_field = strlen(old_field);
322         len_field += (len_t * 8) + 1;  /* add (len_t * 8) for YYYYMMDD -> YYYYMMDDTHHMMSSZ */
323
324         field = calloc(len_field, sizeof(char)); /* add (len_t * 8) for YYYYMMDD -> YYYYMMDDTHHMMSSZ */
325         if (NULL == field) {
326                 /* LCOV_EXCL_START */
327                 ERR("calloc() Fail");
328                 g_strfreev(t);
329                 return CALENDAR_ERROR_OUT_OF_MEMORY;
330                 /* LCOV_EXCL_STOP */
331         }
332
333         struct tm tm = {0};
334         time_t tt = 0;
335
336         int len = 0;
337         int i;
338         for (i = 0; i < len_t; i++) {
339                 int y = 0, m = 0, d = 0;
340                 int h = 0, n = 0, s = 0;
341                 switch (old_type) {
342                 case CALENDAR_TIME_UTIME:
343                         sscanf(t[i], CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ, &y, &m, &d, &h, &n, &s);
344                         break;
345
346                 case CALENDAR_TIME_LOCALTIME:
347                         switch (strlen(t[i])) {
348                         case 8: /* YYYYMMDD */
349                                 sscanf(t[i], CAL_DATETIME_FORMAT_YYYYMMDD, &y, &m, &d);
350                                 break;
351
352                         case 15: /* YYYYMMDDTHHMMSS */
353                                 sscanf(t[i], CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS, &y, &m, &d, &h, &n, &s);
354                                 break;
355                         }
356                         break;
357                 }
358
359                 tm.tm_year = y - 1900;
360                 tm.tm_mon = m - 1;
361                 tm.tm_mday = d;
362                 tm.tm_hour = h;
363                 tm.tm_min = n;
364                 tm.tm_sec = s;
365
366                 char buf[CAL_STR_SHORT_LEN32] = {0};
367                 switch (new_type) {
368                 case CALENDAR_TIME_UTIME:
369                         switch (strlen(t[i])) {
370                         case 8: /* YYYYMMDD */
371                         case 15: /* YYYYMMDDTHHMMSS */
372                                 tt = timelocal(&tm) - time_diff;
373                                 gmtime_r(&tt, &tm);
374                                 snprintf(buf, sizeof(buf), "%s"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ,
375                                                 i == 0 ? "" : ",", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
376                                                 tm.tm_hour, tm.tm_min, tm.tm_sec);
377                                 break;
378
379                         case 16: /* YYYYMMDDTHHMMSSZ */
380                                 tt = timegm(&tm) - time_diff;
381                                 gmtime_r(&tt, &tm);
382                                 snprintf(buf, sizeof(buf), "%s"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ,
383                                                 i == 0 ? "" : ",", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
384                                                 tm.tm_hour, tm.tm_min, tm.tm_sec);
385                                 break;
386                         }
387
388                         break;
389
390                 case CALENDAR_TIME_LOCALTIME:
391                         switch (strlen(t[i])) {
392                         case 8: /* YYYYMMDD */
393                                 tt = timegm(&tm) - time_diff;
394                                 gmtime_r(&tt, &tm);
395                                 snprintf(buf, sizeof(buf), "%s"CAL_DATETIME_FORMAT_YYYYMMDD,
396                                                 i == 0 ? "" : ",", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);
397                                 break;
398                         case 15: /* YYYYMMDDTHHMMSS */
399                                 tt = timegm(&tm) - time_diff;
400                                 gmtime_r(&tt, &tm);
401                                 snprintf(buf, sizeof(buf), "%s"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSS,
402                                                 i == 0 ? "" : ",", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
403                                                 tm.tm_hour, tm.tm_min, tm.tm_sec);
404                                 break;
405                         case 16: /* YYYYMMDDTHHMMSSZ */
406                                 tt = timegm(&tm) - time_diff;
407                                 localtime_r(&tt, &tm);
408                                 snprintf(buf, sizeof(buf), "%s"CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ,
409                                                 i == 0 ? "" : ",", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
410                                                 tm.tm_hour, tm.tm_min, tm.tm_sec);
411                                 break;
412                         }
413                         break;
414                 }
415                 len += snprintf(field + len, len_field -len, "%s", buf);
416                 DBG("[%s]", field);
417         }
418         g_strfreev(t);
419
420         if (new_field)
421                 *new_field = field;
422         else
423                 free(field);
424
425         return CALENDAR_ERROR_NONE;
426 }
427
428 static int __update_exdate(cal_event_s *rec, time_t time_diff)
429 {
430         RETV_IF(NULL == rec, CALENDAR_ERROR_INVALID_PARAMETER);
431
432         if (NULL == rec->exdate || '\0' == *rec->exdate)
433                 return CALENDAR_ERROR_NONE;
434         if (0 == time_diff)
435                 return CALENDAR_ERROR_NONE;
436
437         int ret;
438         calendar_record_h db_record = NULL;
439         ret = cal_db_get_record(_calendar_event._uri, rec->index, &db_record);
440         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_db_get_record() Fail(%d)", ret);
441
442         char *db_tzid = NULL;
443         calendar_record_get_str_p(db_record, _calendar_event.start_tzid, &db_tzid);
444         calendar_time_s ct = {0};
445         calendar_record_get_caltime(db_record, _calendar_event.start_time, &ct);
446
447         char *new_exdate = NULL;
448         __get_time_shifted_field(rec->exdate, ct.type, rec->start.type, time_diff, &new_exdate);
449         free(rec->exdate);
450         rec->exdate = new_exdate;
451         DBG("new exdate[%s]", new_exdate);
452
453         calendar_record_destroy(db_record, true);
454
455         return CALENDAR_ERROR_NONE;
456 }
457
458 static int __update_recurrence_id(calendar_record_h exception, int old_type, int new_type, time_t time_diff)
459 {
460         CAL_FN_CALL();
461
462         cal_event_s *rec = (cal_event_s *)exception;
463         RETV_IF(NULL == rec, CALENDAR_ERROR_INVALID_PARAMETER);
464
465         if (NULL == rec->recurrence_id) {
466                 DBG("No recurrence_id");
467                 return CALENDAR_ERROR_NONE;
468         }
469
470         char *new_recurrence_id = NULL;
471         __get_time_shifted_field(rec->recurrence_id, rec->start.type, new_type, time_diff, &new_recurrence_id);
472         free(rec->recurrence_id);
473         rec->recurrence_id = new_recurrence_id;
474         DBG("new recurrence_id[%s]", new_recurrence_id);
475
476         return CALENDAR_ERROR_NONE;
477 }
478
479 static int __update_record(calendar_record_h record, int is_dirty_in_time)
480 {
481         int ret = 0;
482         char query[CAL_DB_SQL_MAX_LEN] = {0};
483         char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
484         char dtend_datetime[CAL_STR_SHORT_LEN32] = {0};
485         sqlite3_stmt *stmt = NULL;
486         cal_event_s* event =  (cal_event_s*)(record);
487         cal_rrule_s *rrule = NULL;
488         int has_alarm = 0;
489         int timezone_id = 0;
490         int input_ver = 0;
491
492         RETV_IF(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
493         RETV_IF(false == _cal_db_event_check_calendar_book_type(record), CALENDAR_ERROR_INVALID_PARAMETER);
494
495
496         ret = cal_db_event_check_value_validation(event);
497         if (CALENDAR_ERROR_NONE != ret) {
498                 /* LCOV_EXCL_START */
499                 ERR("cal_db_event_check_value_validation() Fail(%d)", ret);
500                 return ret;
501                 /* LCOV_EXCL_STOP */
502         }
503
504         /* access control */
505         if (cal_access_control_have_write_permission(event->calendar_id) == false) {
506                 /* LCOV_EXCL_START */
507                 ERR("cal_access_control_have_write_permission() Fail");
508                 return CALENDAR_ERROR_PERMISSION_DENIED;
509                 /* LCOV_EXCL_STOP */
510         }
511
512         if (event->common.properties_flags) {
513                 if (DIRTY_INIT == is_dirty_in_time)
514                         is_dirty_in_time = __is_dirty_in_time(record);
515
516                 return _cal_db_event_update_dirty(record, is_dirty_in_time);
517         }
518
519         int time_diff = 0;
520         calendar_time_s ct = {0};
521         if (DIRTY_IN_TIME == is_dirty_in_time) {
522                 calendar_record_h old_record = NULL;
523                 ret = cal_db_get_record(_calendar_event._uri, event->index, &old_record);
524                 if (CALENDAR_ERROR_NONE != ret) {
525                         /* LCOV_EXCL_START */
526                         ERR("calendar_db_get_record() Fail(%d)", ret);
527                         return ret;
528                         /* LCOV_EXCL_STOP */
529                 }
530
531                 /* get time diff */
532                 char *old_tzid = NULL;
533                 calendar_record_get_str_p(old_record, _calendar_event.start_tzid, &old_tzid);
534                 calendar_record_get_caltime(old_record, _calendar_event.start_time, &ct);
535                 time_diff = __get_time_diff(old_tzid, &ct, event->start_tzid, &event->start);
536                 calendar_record_destroy(old_record, true);
537         }
538
539         has_alarm = cal_db_alarm_has_alarm(event->alarm_list);
540         cal_db_timezone_search_with_tzid(event->calendar_id, event->start_tzid, &timezone_id);
541         input_ver = cal_db_util_get_next_ver();
542
543         int is_allday = 0;
544         if (CALENDAR_TIME_LOCALTIME == event->start.type
545                         && (0 == event->start.time.date.hour)
546                         && (0 == event->start.time.date.minute)
547                         && (0 == event->start.time.date.second)
548                         && (0 == event->end.time.date.hour)
549                         && (0 == event->end.time.date.minute)
550                         && (0 == event->end.time.date.second)) {
551                 is_allday = 1;
552         }
553         snprintf(query, sizeof(query), "UPDATE %s SET "
554                         "changed_ver = %d,"
555                         "type = %d,"
556                         "summary = ?,"
557                         "description = ?,"
558                         "location = ?,"
559                         "categories = ?,"
560                         "exdate = ?,"
561                         "task_status = %d,"
562                         "priority = %d,"
563                         "timezone = %d, "
564                         "contact_id = %d, "
565                         "busy_status = %d, "
566                         "sensitivity = %d, "
567                         "uid = ?, "
568                         "organizer_name = ?, "
569                         "organizer_email = ?, "
570                         "meeting_status = %d, "
571                         "calendar_id = %d, "
572                         "original_event_id = %d,"
573                         "latitude = %lf,"
574                         "longitude = %lf,"
575                         "email_id = %d,"
576                         "completed_time = %lld,"
577                         "progress = %d, "
578                         "dtstart_type = %d, "
579                         "dtstart_utime = %lld, "
580                         "dtstart_datetime = ?, "
581                         "dtstart_tzid = ?, "
582                         "dtend_type = %d, "
583                         "dtend_utime = %lld, "
584                         "dtend_datetime = ?, "
585                         "dtend_tzid = ?, "
586                         "last_mod = strftime('%%s', 'now'), "
587                         "rrule_id = %d, "
588                         "recurrence_id = ?, "
589                         "rdate = ?, "
590                         "has_attendee = %d, "
591                         "has_alarm = %d, "
592                         "system_type = %d, "
593                         "updated = %d, "
594                         "sync_data1 = ?, "
595                         "sync_data2 = ?, "
596                         "sync_data3 = ?, "
597                         "sync_data4 = ?,"
598                         "has_exception = %d, "
599                         "has_extended = %d, "
600                         "freq = %d, "
601                         "is_allday = %d "
602                         "WHERE id = %d;",
603                 CAL_TABLE_SCHEDULE,
604                 input_ver,
605                 CAL_SCH_TYPE_EVENT,/*event->cal_type,*/
606                 event->event_status,
607                 event->priority,
608                 event->timezone ? event->timezone : timezone_id,
609                 event->contact_id,
610                 event->busy_status,
611                 event->sensitivity,
612                 event->meeting_status,
613                 event->calendar_id,
614                 event->original_event_id,
615                 event->latitude,
616                 event->longitude,
617                 event->email_id,
618                 (long long int)0, /* event->completed_time */
619                 0, /* event->progress, */
620                 event->start.type,
621                 event->start.type == CALENDAR_TIME_UTIME ? event->start.time.utime : 0,
622                 event->end.type,
623                 event->end.type == CALENDAR_TIME_UTIME ? event->end.time.utime : 0,
624                 0 < event->freq ? 1 : 0,
625                 (event->attendee_list && 0 < event->attendee_list->count) ? 1 : 0,
626                 has_alarm,
627                 event->system_type,
628                 event->updated,
629                 (event->exception_list && 0 < event->exception_list->count) ? 1 : 0,
630                 (event->extended_list && 0 < event->extended_list->count) ? 1 : 0,
631                 event->freq,
632                 is_allday,
633                 event->index);
634
635         ret = cal_db_util_query_prepare(query, &stmt);
636         if (CALENDAR_ERROR_NONE != ret) {
637                 /* LCOV_EXCL_START */
638                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
639                 SECURE("query[%s]", query);
640                 return ret;
641                 /* LCOV_EXCL_STOP */
642         }
643
644         int index = 1;
645
646         if (event->summary)
647                 cal_db_util_stmt_bind_text(stmt, index, event->summary);
648         index++;
649
650         if (event->description)
651                 cal_db_util_stmt_bind_text(stmt, index, event->description);
652         index++;
653
654         if (event->location)
655                 cal_db_util_stmt_bind_text(stmt, index, event->location);
656         index++;
657
658         if (event->categories)
659                 cal_db_util_stmt_bind_text(stmt, index, event->categories);
660         index++;
661
662         if (event->exdate) {
663                 if (DIRTY_IN_TIME == is_dirty_in_time)
664                         __update_exdate(event, time_diff);
665
666                 cal_db_util_stmt_bind_text(stmt, index, event->exdate);
667         }
668         index++;
669
670         if (event->uid)
671                 cal_db_util_stmt_bind_text(stmt, index, event->uid);
672         index++;
673
674         if (event->organizer_name)
675                 cal_db_util_stmt_bind_text(stmt, index, event->organizer_name);
676         index++;
677
678         if (event->organizer_email)
679                 cal_db_util_stmt_bind_text(stmt, index, event->organizer_email);
680         index++;
681
682         if (CALENDAR_TIME_LOCALTIME == event->start.type) {
683                 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME,
684                                 event->start.time.date.year,
685                                 event->start.time.date.month,
686                                 event->start.time.date.mday,
687                                 event->start.time.date.hour,
688                                 event->start.time.date.minute,
689                                 event->start.time.date.second);
690                 cal_db_util_stmt_bind_text(stmt, index, dtstart_datetime);
691         }
692         index++;
693
694         if (event->start_tzid)
695                 cal_db_util_stmt_bind_text(stmt, index, event->start_tzid);
696         index++;
697
698         if (CALENDAR_TIME_LOCALTIME == event->end.type) {
699                 snprintf(dtend_datetime, sizeof(dtend_datetime), CAL_FORMAT_LOCAL_DATETIME,
700                                 event->end.time.date.year,
701                                 event->end.time.date.month,
702                                 event->end.time.date.mday,
703                                 event->end.time.date.hour,
704                                 event->end.time.date.minute,
705                                 event->end.time.date.second);
706                 cal_db_util_stmt_bind_text(stmt, index, dtend_datetime);
707         }
708         index++;
709
710         if (event->end_tzid)
711                 cal_db_util_stmt_bind_text(stmt, index, event->end_tzid);
712         index++;
713
714         if (event->recurrence_id)
715                 cal_db_util_stmt_bind_text(stmt, index, event->recurrence_id);
716         index++;
717         if (event->rdate)
718                 cal_db_util_stmt_bind_text(stmt, index, event->rdate);
719         index++;
720         if (event->sync_data1)
721                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data1);
722         index++;
723         if (event->sync_data2)
724                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data2);
725         index++;
726         if (event->sync_data3)
727                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data3);
728         index++;
729         if (event->sync_data4)
730                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data4);
731         index++;
732
733         ret = cal_db_util_stmt_step(stmt);
734         sqlite3_finalize(stmt);
735         if (CALENDAR_ERROR_NONE != ret) {
736                 /* LCOV_EXCL_START */
737                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
738                 return ret;
739                 /* LCOV_EXCL_STOP */
740         }
741
742         /*
743          * update parent event changed ver in case this event is exception mod
744          * which is original_event_id > 0
745          */
746         cal_db_event_update_original_event_version(event->original_event_id, input_ver);
747         cal_db_rrule_get_rrule_from_record(record, &rrule);
748         cal_db_rrule_update_record(event->index, rrule); /* if rrule turns none, update 0. */
749         CAL_FREE(rrule);
750
751         if (DIRTY_IN_TIME == is_dirty_in_time) {
752                 cal_db_instance_discard_record(event->index);
753                 cal_db_instance_publish_record(record);
754
755         } else {
756                 cal_db_instance_update_exdate_del(event->index, event->exdate);
757         }
758
759         while ((event->uid && *event->uid) && (NULL == event->recurrence_id || '\0' == *event->recurrence_id)) {
760                 /* check if exception mod has. recurrence_id */
761                 GList *list = NULL;
762                 list = cal_db_event_get_list_with_uid(event->uid, event->index);
763                 if (NULL == list)
764                         break;
765                 GList *l = g_list_first(list);
766                 if (l) {
767                         int child_id = GPOINTER_TO_INT(l->data);
768                         /* update children original_event_id */
769                         cal_db_event_update_child_origina_event_id(child_id, event->index);
770                         char *recurrence_id = NULL;
771                         recurrence_id = cal_db_event_get_recurrence_id_from_exception(child_id);
772                         if (recurrence_id) {
773                                 /* remove parent instance */
774                                 cal_db_event_apply_recurrence_id(event->index, event, recurrence_id, child_id);
775                                 free(recurrence_id);
776                         }
777                         l = g_list_next(l);
778                 }
779                 g_list_free(list);
780                 break;
781         }
782
783         cal_db_alarm_delete_with_id(event->index);
784         cal_db_attendee_delete_with_id(event->index);
785         cal_db_extended_delete_with_id(event->index, CALENDAR_RECORD_TYPE_EVENT);
786
787         if (event->alarm_list && 0 < event->alarm_list->count) {
788                 ret = cal_db_alarm_insert_records(event->alarm_list, event->index);
789                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_alarm_insert_records() Fail(%x)", ret);
790         }
791
792         if (event->attendee_list && 0 < event->attendee_list->count) {
793                 ret = cal_db_attendee_insert_records(event->attendee_list, event->index);
794                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_attendee_insert_records() Fail(%x)", ret);
795         }
796
797         if (event->exception_list && 0 < event->exception_list->count) {
798                 ret = _cal_db_event_exception_update(event->exception_list, event->index, event->calendar_id, is_dirty_in_time, time_diff, ct.type, event->start.type);
799                 WARN_IF(CALENDAR_ERROR_NONE != ret, "_cal_db_event_exception_update() Fail(%d)", ret);
800         }
801
802         if (event->extended_list && 0 < event->extended_list->count) {
803                 ret = cal_db_extended_insert_records(event->extended_list, event->index, CALENDAR_RECORD_TYPE_EVENT);
804                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_extended_insert_records() Fail(%d)", ret);
805         }
806
807         cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
808
809         return CALENDAR_ERROR_NONE;
810 }
811
812 static int _cal_db_event_update_record(calendar_record_h record)
813 {
814         return __update_record(record, DIRTY_INIT);
815 }
816
817 static int _cal_db_event_add_exdate(int original_event_id, char* recurrence_id)
818 {
819         int ret = 0;
820         char query[CAL_DB_SQL_MAX_LEN];
821         sqlite3_stmt *stmt = NULL;
822
823         RETV_IF(original_event_id < 0, CALENDAR_ERROR_NONE);
824         DBG("This is exception mod event");
825         RETVM_IF(NULL == recurrence_id, CALENDAR_ERROR_NONE, "This event should have recurrence_id");
826         DBG("Exdate parent(id:%d) and recurrence_id[%s]", original_event_id, recurrence_id);
827
828         /* get exdate from original event */
829         snprintf(query, sizeof(query), "SELECT exdate FROM %s WHERE id = %d ",
830                         CAL_TABLE_SCHEDULE, original_event_id);
831
832         ret = cal_db_util_query_prepare(query, &stmt);
833         if (CALENDAR_ERROR_NONE != ret) {
834                 /* LCOV_EXCL_START */
835                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
836                 SECURE("query[%s]", query);
837                 return ret;
838                 /* LCOV_EXCL_STOP */
839         }
840
841         /* add recurrence id to end of the exdate of original event. */
842         const unsigned char *temp = NULL;
843         int len = 0;
844         char *exdate = NULL;
845         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
846                 temp = sqlite3_column_text(stmt, 0);
847                 if (NULL == temp || strlen((char *)temp) < 1) {
848                         exdate = cal_strdup(recurrence_id);
849                         DBG("append first exdate[%s]", exdate);
850                 } else {
851                         if (strstr((char *)temp, recurrence_id)) {
852                                 DBG("warn: recurrence id already is registered to exdate");
853                                 sqlite3_finalize(stmt);
854                                 return CALENDAR_ERROR_NONE;
855                         }
856                         len = strlen((const char *)temp) + strlen(recurrence_id) + 2;
857                         exdate = calloc(len, sizeof(char));
858                         if (NULL == exdate) {
859                                 /* LCOV_EXCL_START */
860                                 ERR("calloc() Fail");
861                                 sqlite3_finalize(stmt);
862                                 return CALENDAR_ERROR_OUT_OF_MEMORY;
863                                 /* LCOV_EXCL_STOP */
864                         }
865                         snprintf(exdate, len, "%s,%s", temp, recurrence_id);
866                         DBG("append [%s] to already has exdate [%s]", temp, recurrence_id);
867                 }
868         } else {
869                 DBG("Failed to get exdate: event_id(%d)", original_event_id);
870         }
871         sqlite3_finalize(stmt);
872         stmt = NULL;
873
874         /* update exdate */
875         DBG("update to recurrence id to exdate[%s]", exdate);
876         int input_ver = cal_db_util_get_next_ver();
877         snprintf(query, sizeof(query), "UPDATE %s SET exdate = ?, changed_ver=%d WHERE id = %d ",
878                         CAL_TABLE_SCHEDULE, input_ver, original_event_id);
879
880         ret = cal_db_util_query_prepare(query, &stmt);
881         if (CALENDAR_ERROR_NONE != ret) {
882                 /* LCOV_EXCL_START */
883                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
884                 SECURE("query[%s]", query);
885                 free(exdate);
886                 return ret;
887                 /* LCOV_EXCL_STOP */
888         }
889
890         int index = 1;
891         cal_db_util_stmt_bind_text(stmt, index, exdate);
892
893         ret = cal_db_util_stmt_step(stmt);
894         sqlite3_finalize(stmt);
895         free(exdate);
896         if (CALENDAR_ERROR_NONE != ret) {
897                 /* LCOV_EXCL_START */
898                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
899                 return ret;
900                 /* LCOV_EXCL_STOP */
901         }
902
903         return CALENDAR_ERROR_NONE;
904 }
905
906 static int _cal_db_event_delete_record(int id)
907 {
908         int ret = CALENDAR_ERROR_NONE;
909         int calendar_book_id;
910         char query[CAL_DB_SQL_MAX_LEN] = {0};
911         int created_ver = 0;
912         int original_event_id = 0;
913         char *recurrence_id = NULL;
914         calendar_book_sync_event_type_e sync_event_type = CALENDAR_BOOK_SYNC_EVENT_FOR_ME;
915
916         DBG("delete record(id:%d)", id);
917         RETVM_IF(id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "id(%d) < 0", id);
918
919         /* get calendar_id, created_ver, original_event_id, recurrence_id */
920         ret = _cal_db_event_get_deleted_data(id, &calendar_book_id, &created_ver, &original_event_id, &recurrence_id);
921         if (CALENDAR_ERROR_NONE != ret) {
922                 /* LCOV_EXCL_START */
923                 DBG("_cal_db_event_get_deleted_data() Fail");
924                 return ret;
925                 /* LCOV_EXCL_STOP */
926         }
927
928         /* access control */
929         if (cal_access_control_have_write_permission(calendar_book_id) == false) {
930                 /* LCOV_EXCL_START */
931                 ERR("Fail");
932                 CAL_FREE(recurrence_id);
933                 return CALENDAR_ERROR_PERMISSION_DENIED;
934                 /* LCOV_EXCL_STOP */
935         }
936
937         if (0 < original_event_id) {
938                 /* start:add record to exdate if this record is exception mod. */
939                 _cal_db_event_add_exdate(original_event_id, recurrence_id);
940         }
941         CAL_FREE(recurrence_id);
942
943         snprintf(query, sizeof(query), "SELECT sync_event FROM %s WHERE id = %d ", CAL_TABLE_CALENDAR, calendar_book_id);
944         ret = cal_db_util_query_get_first_int_result(query, NULL, (int *)&sync_event_type);
945         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_query_get_first_int_result() Fail(%d)", ret);
946
947         DBG("sync_event_type(%d)", sync_event_type);
948         if (sync_event_type == CALENDAR_BOOK_SYNC_EVENT_FOR_EVERY_AND_REMAIN) {
949                 DBG("set is_delete");
950                 snprintf(query, sizeof(query), "UPDATE %s SET is_deleted = 1, changed_ver = %d, "
951                                 "last_mod = strftime('%%s','now') WHERE id = %d ",
952                                 CAL_TABLE_SCHEDULE, cal_db_util_get_next_ver(), id);
953
954                 ret = cal_db_util_query_exec(query);
955                 if (CALENDAR_ERROR_NONE != ret) {
956                         /* LCOV_EXCL_START */
957                         ERR("cal_db_util_query_exec() Fail(%d)", ret);
958                         SECURE("[%s]", query);
959                         return ret;
960                         /* LCOV_EXCL_STOP */
961                 }
962
963         } else {
964                 cal_db_util_get_next_ver();
965
966                 DBG("delete event");
967                 snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d ", CAL_TABLE_SCHEDULE, id);
968                 ret = cal_db_util_query_exec(query);
969                 if (CALENDAR_ERROR_NONE != ret) {
970                         /* LCOV_EXCL_START */
971                         ERR("cal_db_util_query_exec() Fail(%d)", ret);
972                         SECURE("[%s]", query);
973                         return ret;
974                         /* LCOV_EXCL_STOP */
975                 }
976                 DBG("attendee, alarm and rrule is deleted by trigger");
977         }
978
979         cal_db_instance_discard_record(id);
980         cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
981         return CALENDAR_ERROR_NONE;
982 }
983
984 static int _cal_db_event_get_all_records(int offset, int limit, calendar_list_h* out_list)
985 {
986         int ret = CALENDAR_ERROR_NONE;
987         char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
988         char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
989         sqlite3_stmt *stmt = NULL;
990
991         RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
992
993         ret = calendar_list_create(out_list);
994         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
995
996         if (0 < offset)
997                 snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
998
999         if (0 < limit)
1000                 snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
1001
1002         char *query_str = NULL;
1003         cal_db_append_string(&query_str, "SELECT * FROM");
1004         cal_db_append_string(&query_str, CAL_VIEW_TABLE_EVENT);
1005         cal_db_append_string(&query_str, limitquery);
1006         cal_db_append_string(&query_str, offsetquery);
1007
1008         ret = cal_db_util_query_prepare(query_str, &stmt);
1009         if (CALENDAR_ERROR_NONE != ret) {
1010                 /* LCOV_EXCL_START */
1011                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1012                 SECURE("query[%s]", query_str);
1013                 calendar_list_destroy(*out_list, true);
1014                 *out_list = NULL;
1015                 free(query_str);
1016                 return ret;
1017                 /* LCOV_EXCL_STOP */
1018         }
1019
1020         SECURE("[TEST]---------query[%s]", query_str);
1021         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
1022                 calendar_record_h record;
1023                 int exception = 0, extended = 0;
1024                 ret = calendar_record_create(_calendar_event._uri, &record);
1025                 if (CALENDAR_ERROR_NONE != ret) {
1026                         /* LCOV_EXCL_START */
1027                         ERR("calendar_record_create() Fail(%d)", ret);
1028                         calendar_list_destroy(*out_list, true);
1029                         *out_list = NULL;
1030                         sqlite3_finalize(stmt);
1031                         CAL_FREE(query_str);
1032                         return ret;
1033                         /* LCOV_EXCL_STOP */
1034                 }
1035                 _cal_db_event_get_stmt(stmt, true, record, &exception, &extended);
1036
1037                 /* child */
1038                 int has_attendee = 0, has_alarm = 0;
1039                 int record_id = 0;
1040                 cal_event_s* pevent = (cal_event_s*) record;
1041                 calendar_record_get_int(record, _calendar_event.id, &record_id);
1042                 if (CALENDAR_ERROR_NONE == calendar_record_get_int(record, _calendar_event.has_attendee, &has_attendee)) {
1043                         if (has_attendee == 1)
1044                                 cal_db_attendee_get_records(record_id, pevent->attendee_list);
1045                 }
1046                 if (CALENDAR_ERROR_NONE == calendar_record_get_int(record, _calendar_event.has_alarm, &has_alarm)) {
1047                         if (has_alarm == 1)
1048                                 cal_db_alarm_get_records(record_id, pevent->alarm_list);
1049                 }
1050
1051                 if (exception == 1)
1052                         _cal_db_event_exception_get_records(record_id, pevent->exception_list);
1053
1054                 if (extended == 1)
1055                         cal_db_extended_get_records(record_id, CALENDAR_RECORD_TYPE_EVENT, pevent->extended_list);
1056
1057                 ret = calendar_list_add(*out_list, record);
1058                 if (CALENDAR_ERROR_NONE != ret) {
1059                         /* LCOV_EXCL_START */
1060                         ERR("calendar_list_add() Fail(%d)", ret);
1061                         calendar_list_destroy(*out_list, true);
1062                         *out_list = NULL;
1063                         calendar_record_destroy(record, true);
1064                         sqlite3_finalize(stmt);
1065                         CAL_FREE(query_str);
1066                         return ret;
1067                         /* LCOV_EXCL_STOP */
1068                 }
1069         }
1070
1071         sqlite3_finalize(stmt);
1072         CAL_FREE(query_str);
1073         return CALENDAR_ERROR_NONE;
1074 }
1075
1076 static int _cal_db_event_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
1077 {
1078         cal_query_s *que = NULL;
1079         calendar_list_h list = NULL;
1080         int ret = CALENDAR_ERROR_NONE;
1081         char *condition = NULL;
1082         char *projection = NULL;
1083         GSList *bind_text = NULL, *cursor = NULL;
1084         sqlite3_stmt *stmt = NULL;
1085         int i = 0;
1086         char *table_name;
1087
1088         if (NULL == query || NULL == out_list) {
1089                 /* LCOV_EXCL_START */
1090                 ERR("Invalid parameter");
1091                 return CALENDAR_ERROR_INVALID_PARAMETER;
1092                 /* LCOV_EXCL_STOP */
1093         }
1094
1095         que = (cal_query_s *)query;
1096
1097         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EVENT)) {
1098                 table_name = cal_strdup(CAL_VIEW_TABLE_EVENT);
1099         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR)) {
1100                 table_name = cal_strdup(CAL_VIEW_TABLE_EVENT_CALENDAR);
1101         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE)) {
1102                 table_name = cal_strdup(CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE);
1103         } else {
1104                 /* LCOV_EXCL_START */
1105                 ERR("uri(%s) not support get records with query", que->view_uri);
1106                 return CALENDAR_ERROR_INVALID_PARAMETER;
1107                 /* LCOV_EXCL_STOP */
1108         }
1109
1110         /* make filter */
1111         if (que->filter) {
1112                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
1113                 if (CALENDAR_ERROR_NONE != ret) {
1114                         CAL_FREE(table_name);
1115                         /* LCOV_EXCL_START */
1116                         ERR("cal_db_query_create_condition() Fail(%d), ret");
1117                         return ret;
1118                         /* LCOV_EXCL_STOP */
1119                 }
1120         }
1121
1122         /* make: projection */
1123         ret = cal_db_query_create_projection(query, &projection);
1124
1125         char *query_str = NULL;
1126         /* query: projection */
1127         if (projection) {
1128                 cal_db_append_string(&query_str, "SELECT");
1129                 cal_db_append_string(&query_str, projection);
1130                 cal_db_append_string(&query_str, "FROM");
1131                 cal_db_append_string(&query_str, table_name);
1132                 CAL_FREE(projection);
1133         } else {
1134                 cal_db_append_string(&query_str, "SELECT * FROM");
1135                 cal_db_append_string(&query_str, table_name);
1136         }
1137         CAL_FREE(table_name);
1138
1139         /* query: condition */
1140         if (condition) {
1141                 cal_db_append_string(&query_str, "WHERE (");
1142                 cal_db_append_string(&query_str, condition);
1143                 cal_db_append_string(&query_str, ")");
1144         }
1145
1146         /* order */
1147         char *order = NULL;
1148         ret = cal_db_query_create_order(query, condition, &order);
1149         if (order) {
1150                 cal_db_append_string(&query_str, order);
1151                 CAL_FREE(order);
1152         }
1153         CAL_FREE(condition);
1154
1155         /* limit, offset */
1156         char buf[CAL_STR_SHORT_LEN32] = {0};
1157         if (0 < limit) {
1158                 snprintf(buf, sizeof(buf), "LIMIT %d", limit);
1159                 cal_db_append_string(&query_str, buf);
1160
1161                 if (0 < offset) {
1162                         snprintf(buf, sizeof(buf), "OFFSET %d", offset);
1163                         cal_db_append_string(&query_str, buf);
1164                 }
1165         }
1166         DBG("%s", query_str);
1167
1168         /* query */
1169         ret = cal_db_util_query_prepare(query_str, &stmt);
1170         if (CALENDAR_ERROR_NONE != ret) {
1171                 /* LCOV_EXCL_START */
1172                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1173                 SECURE("query[%s]", query_str);
1174                 if (bind_text) {
1175                         g_slist_free_full(bind_text, free);
1176                         bind_text = NULL;
1177                 }
1178                 free(query_str);
1179                 return ret;
1180                 /* LCOV_EXCL_STOP */
1181         }
1182
1183         /* bind text */
1184         if (bind_text) {
1185                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
1186                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
1187         }
1188
1189         ret = calendar_list_create(&list);
1190         if (CALENDAR_ERROR_NONE != ret) {
1191                 /* LCOV_EXCL_START */
1192                 ERR("calendar_list_create() Fail(%d)", ret);
1193                 if (bind_text) {
1194                         g_slist_free_full(bind_text, free);
1195                         bind_text = NULL;
1196                 }
1197                 sqlite3_finalize(stmt);
1198                 CAL_FREE(query_str);
1199                 return ret;
1200                 /* LCOV_EXCL_STOP */
1201         }
1202
1203         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
1204                 calendar_record_h record;
1205                 int exception = 1, extended = 1;
1206                 int attendee = 1, alarm = 1;
1207
1208                 ret = calendar_record_create(_calendar_event._uri, &record);
1209                 if (CALENDAR_ERROR_NONE != ret) {
1210                         /* LCOV_EXCL_START */
1211                         ERR("calendar_record_create() Fail(%d)", ret);
1212                         calendar_list_destroy(list, true);
1213                         if (bind_text) {
1214                                 g_slist_free_full(bind_text, free);
1215                                 bind_text = NULL;
1216                         }
1217                         sqlite3_finalize(stmt);
1218                         CAL_FREE(query_str);
1219                         return ret;
1220                         /* LCOV_EXCL_STOP */
1221                 }
1222                 if (0 < que->projection_count) {
1223                         cal_record_set_projection(record, que->projection, que->projection_count, que->property_count);
1224                         _cal_db_event_get_projection_stmt(stmt, que->projection, que->projection_count, record);
1225                 } else {
1226                         cal_event_s *event = NULL;
1227                         _cal_db_event_get_stmt(stmt, true, record, &exception, &extended);
1228                         event = (cal_event_s*)(record);
1229                         if (event) {
1230                                 attendee = event->has_attendee;
1231                                 alarm = event->has_alarm;
1232                         }
1233                 }
1234
1235                 /* child */
1236                 if (cal_db_query_find_projection_property(query, CAL_PROPERTY_EVENT_CALENDAR_ALARM) == true && alarm == 1) {
1237                         cal_event_s* pevent = (cal_event_s*) record;
1238                         cal_db_alarm_get_records(pevent->index, pevent->alarm_list);
1239                 }
1240                 if (cal_db_query_find_projection_property(query, CAL_PROPERTY_EVENT_CALENDAR_ATTENDEE) == true && attendee == 1) {
1241                         cal_event_s* pevent = (cal_event_s*) record;
1242                         cal_db_attendee_get_records(pevent->index, pevent->attendee_list);
1243                 }
1244                 if (cal_db_query_find_projection_property(query, CAL_PROPERTY_EVENT_EXCEPTION) == true && exception == 1) {
1245                         cal_event_s* pevent = (cal_event_s*) record;
1246                         _cal_db_event_exception_get_records(pevent->index, pevent->exception_list);
1247                 }
1248                 if (cal_db_query_find_projection_property(query, CAL_PROPERTY_EVENT_EXTENDED) == true && extended == 1) {
1249                         cal_event_s* pevent = (cal_event_s*) record;
1250                         cal_db_extended_get_records(pevent->index, CALENDAR_RECORD_TYPE_EVENT, pevent->extended_list);
1251                 }
1252
1253                 ret = calendar_list_add(list, record);
1254                 if (CALENDAR_ERROR_NONE != ret) {
1255                         /* LCOV_EXCL_START */
1256                         ERR("calendar_list_add() Fail(%d)", ret);
1257                         calendar_list_destroy(list, true);
1258                         calendar_record_destroy(record, true);
1259
1260                         if (bind_text) {
1261                                 g_slist_free_full(bind_text, free);
1262                                 bind_text = NULL;
1263                         }
1264                         sqlite3_finalize(stmt);
1265                         CAL_FREE(query_str);
1266                         return ret;
1267                         /* LCOV_EXCL_STOP */
1268                 }
1269         }
1270
1271         if (bind_text) {
1272                 g_slist_free_full(bind_text, free);
1273                 bind_text = NULL;
1274         }
1275
1276         sqlite3_finalize(stmt);
1277         CAL_FREE(query_str);
1278
1279         *out_list = list;
1280         __check_list(list);
1281
1282         return CALENDAR_ERROR_NONE;
1283 }
1284
1285 static int _cal_db_event_delete_records(int ids[], int count)
1286 {
1287         int ret = CALENDAR_ERROR_NONE;
1288         int i = 0;
1289
1290         for (i = 0; i < count; i++) {
1291                 ret = _cal_db_event_delete_record(ids[i]);
1292                 if (CALENDAR_ERROR_NONE != ret) {
1293                         /* LCOV_EXCL_START */
1294                         ERR("_cal_db_event_delete_record() Fail(%d)", ret);
1295                         return ret;
1296                         /* LCOV_EXCL_STOP */
1297                 }
1298         }
1299         return CALENDAR_ERROR_NONE;
1300 }
1301
1302 static int _cal_db_event_get_count(int *out_count)
1303 {
1304         RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
1305
1306         char *query_str = NULL;
1307         cal_db_append_string(&query_str, "SELECT count(*) FROM");
1308         cal_db_append_string(&query_str, CAL_VIEW_TABLE_EVENT);
1309
1310         int ret = 0;
1311         int count = 0;
1312         ret = cal_db_util_query_get_first_int_result(query_str, NULL, &count);
1313         if (CALENDAR_ERROR_NONE != ret) {
1314                 /* LCOV_EXCL_START */
1315                 ERR("cal_db_util_query_get_first_int_result() Fail");
1316                 CAL_FREE(query_str);
1317                 return ret;
1318                 /* LCOV_EXCL_STOP */
1319         }
1320         DBG("count(%d) str[%s]", count, query_str);
1321         CAL_FREE(query_str);
1322
1323         *out_count = count;
1324         return CALENDAR_ERROR_NONE;
1325 }
1326
1327 static int _cal_db_event_get_count_with_query(calendar_query_h query, int *out_count)
1328 {
1329         cal_query_s *que = NULL;
1330         int ret = CALENDAR_ERROR_NONE;
1331         char *condition = NULL;
1332         char *table_name;
1333         int count = 0;
1334         GSList *bind_text = NULL;
1335
1336         que = (cal_query_s *)query;
1337
1338         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EVENT)) {
1339                 table_name = cal_strdup(CAL_VIEW_TABLE_EVENT);
1340         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR)) {
1341                 table_name = cal_strdup(CAL_VIEW_TABLE_EVENT_CALENDAR);
1342         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE)) {
1343                 table_name = cal_strdup(CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE);
1344         } else {
1345                 /* LCOV_EXCL_START */
1346                 ERR("uri(%s) not support get records with query", que->view_uri);
1347                 return CALENDAR_ERROR_INVALID_PARAMETER;
1348                 /* LCOV_EXCL_STOP */
1349         }
1350
1351         /* make filter */
1352         if (que->filter) {
1353                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
1354                 if (CALENDAR_ERROR_NONE != ret) {
1355                         CAL_FREE(table_name);
1356                         /* LCOV_EXCL_START */
1357                         ERR("cal_db_query_create_condition() Fail(%d), ret");
1358                         return ret;
1359                         /* LCOV_EXCL_STOP */
1360                 }
1361         }
1362
1363         char *query_str = NULL;
1364         /* query: select */
1365         cal_db_append_string(&query_str, "SELECT count(*) FROM");
1366         cal_db_append_string(&query_str, table_name);
1367         CAL_FREE(table_name);
1368
1369         /* query: condition */
1370         if (condition) {
1371                 cal_db_append_string(&query_str,  "WHERE (");
1372                 cal_db_append_string(&query_str, condition);
1373                 cal_db_append_string(&query_str, ")");
1374                 CAL_FREE(condition);
1375         }
1376
1377         /* query */
1378         ret = cal_db_util_query_get_first_int_result(query_str, bind_text, &count);
1379         if (CALENDAR_ERROR_NONE != ret) {
1380                 /* LCOV_EXCL_START */
1381                 ERR("cal_db_util_query_get_first_int_result() Fail");
1382                 if (bind_text) {
1383                         g_slist_free_full(bind_text, free);
1384                         bind_text = NULL;
1385                 }
1386                 CAL_FREE(query_str);
1387                 return ret;
1388                 /* LCOV_EXCL_STOP */
1389         }
1390         DBG("count(%d) str[%s]", count, query_str);
1391
1392         if (out_count) *out_count = count;
1393         if (bind_text) {
1394                 g_slist_free_full(bind_text, free);
1395                 bind_text = NULL;
1396         }
1397
1398         CAL_FREE(query_str);
1399         return CALENDAR_ERROR_NONE;
1400 }
1401
1402 static int _cal_db_event_replace_record(calendar_record_h record, int id)
1403 {
1404         int ret = CALENDAR_ERROR_NONE;
1405         char query[CAL_DB_SQL_MAX_LEN] = {0};
1406         char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
1407         char dtend_datetime[CAL_STR_SHORT_LEN32] = {0};
1408         sqlite3_stmt *stmt = NULL;
1409         cal_event_s* event =  (cal_event_s*)(record);
1410         cal_rrule_s *rrule = NULL;
1411         int has_alarm = 0;
1412         int timezone_id = 0;
1413         int input_ver = 0;
1414
1415         RETV_IF(NULL == event, CALENDAR_ERROR_INVALID_PARAMETER);
1416         event->index = id;
1417
1418         /* access control */
1419         if (cal_access_control_have_write_permission(event->calendar_id) == false) {
1420                 /* LCOV_EXCL_START */
1421                 ERR("cal_access_control_have_write_permission() Fail");
1422                 return CALENDAR_ERROR_PERMISSION_DENIED;
1423                 /* LCOV_EXCL_STOP */
1424         }
1425         if (event->common.properties_flags != NULL)
1426                 return _cal_db_event_update_dirty(record, -1);
1427
1428         has_alarm = cal_db_alarm_has_alarm(event->alarm_list);
1429         cal_db_timezone_search_with_tzid(event->calendar_id, event->start_tzid, &timezone_id);
1430         input_ver = cal_db_util_get_next_ver();
1431
1432         int is_allday = 0;
1433         if (CALENDAR_TIME_LOCALTIME == event->start.type
1434                         && (0 == event->start.time.date.hour)
1435                         && (0 == event->start.time.date.minute)
1436                         && (0 == event->start.time.date.second)
1437                         && (0 == event->end.time.date.hour)
1438                         && (0 == event->end.time.date.minute)
1439                         && (0 == event->end.time.date.second)) {
1440                 is_allday = 1;
1441         }
1442
1443         snprintf(query, sizeof(query), "UPDATE %s SET "
1444                         "changed_ver = %d,"
1445                         "type = %d,"
1446                         "summary = ?,"
1447                         "description = ?,"
1448                         "location = ?,"
1449                         "categories = ?,"
1450                         "exdate = ?,"
1451                         "task_status = %d,"
1452                         "priority = %d,"
1453                         "timezone = %d, "
1454                         "contact_id = %d, "
1455                         "busy_status = %d, "
1456                         "sensitivity = %d, "
1457                         "uid = ?, "
1458                         "organizer_name = ?, "
1459                         "organizer_email = ?, "
1460                         "meeting_status = %d, "
1461                         "calendar_id = %d, "
1462                         "original_event_id = %d,"
1463                         "latitude = %lf,"
1464                         "longitude = %lf,"
1465                         "email_id = %d,"
1466                         "completed_time = %lld,"
1467                         "progress = %d, "
1468                         "dtstart_type = %d, "
1469                         "dtstart_utime = %lld, "
1470                         "dtstart_datetime = ?, "
1471                         "dtstart_tzid = ?, "
1472                         "dtend_type = %d, "
1473                         "dtend_utime = %lld, "
1474                         "dtend_datetime = ?, "
1475                         "dtend_tzid = ?, "
1476                         "last_mod = strftime('%%s', 'now'), "
1477                         "rrule_id = %d, "
1478                         "recurrence_id = ?, "
1479                         "rdate = ?, "
1480                         "has_attendee = %d, "
1481                         "has_alarm = %d, "
1482                         "system_type = %d, "
1483                         "updated = %d, "
1484                         "sync_data1 = ?, "
1485                         "sync_data2 = ?, "
1486                         "sync_data3 = ?, "
1487                         "sync_data4 = ?, "
1488                         "freq = %d, "
1489                         "is_allday = %d "
1490                         "WHERE id = %d ",
1491                 CAL_TABLE_SCHEDULE,
1492                 input_ver,
1493                 CAL_SCH_TYPE_EVENT,/*event->cal_type,*/
1494                 event->event_status,
1495                 event->priority,
1496                 event->timezone ? event->timezone : timezone_id,
1497                 event->contact_id,
1498                 event->busy_status,
1499                 event->sensitivity,
1500                 event->meeting_status,
1501                 event->calendar_id,
1502                 event->original_event_id,
1503                 event->latitude,
1504                 event->longitude,
1505                 event->email_id,
1506                 (long long int)0, /* event->completed_time, */
1507                 0, /* event->progress, */
1508                 event->start.type,
1509                 event->start.type == CALENDAR_TIME_UTIME ? event->start.time.utime : 0,
1510                 event->end.type,
1511                 event->end.type == CALENDAR_TIME_UTIME ? event->end.time.utime : 0,
1512                 0 < event->freq ? 1 : 0,
1513                 (event->attendee_list && 0 < event->attendee_list->count) ? 1 : 0,
1514                 has_alarm,
1515                 event->system_type,
1516                 event->updated,
1517                 event->freq,
1518                 is_allday,
1519                 id);
1520
1521         ret = cal_db_util_query_prepare(query, &stmt);
1522         if (CALENDAR_ERROR_NONE != ret) {
1523                 /* LCOV_EXCL_START */
1524                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1525                 SECURE("query[%s]", query);
1526                 return ret;
1527                 /* LCOV_EXCL_STOP */
1528         }
1529
1530         int index = 1;
1531
1532         if (event->summary)
1533                 cal_db_util_stmt_bind_text(stmt, index, event->summary);
1534         index++;
1535
1536         if (event->description)
1537                 cal_db_util_stmt_bind_text(stmt, index, event->description);
1538         index++;
1539
1540         if (event->location)
1541                 cal_db_util_stmt_bind_text(stmt, index, event->location);
1542         index++;
1543
1544         if (event->categories)
1545                 cal_db_util_stmt_bind_text(stmt, index, event->categories);
1546         index++;
1547
1548         if (event->exdate)
1549                 cal_db_util_stmt_bind_text(stmt, index, event->exdate);
1550         index++;
1551
1552         if (event->uid)
1553                 cal_db_util_stmt_bind_text(stmt, index, event->uid);
1554         index++;
1555
1556         if (event->organizer_name)
1557                 cal_db_util_stmt_bind_text(stmt, index, event->organizer_name);
1558         index++;
1559
1560         if (event->organizer_email)
1561                 cal_db_util_stmt_bind_text(stmt, index, event->organizer_email);
1562         index++;
1563
1564         if (CALENDAR_TIME_LOCALTIME == event->start.type) {
1565                 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME,
1566                                 event->start.time.date.year,
1567                                 event->start.time.date.month,
1568                                 event->start.time.date.mday,
1569                                 event->start.time.date.hour,
1570                                 event->start.time.date.minute,
1571                                 event->start.time.date.second);
1572                 cal_db_util_stmt_bind_text(stmt, index, dtstart_datetime);
1573         }
1574         index++;
1575
1576         if (event->start_tzid)
1577                 cal_db_util_stmt_bind_text(stmt, index, event->start_tzid);
1578         index++;
1579
1580         if (CALENDAR_TIME_LOCALTIME == event->end.type) {
1581                 snprintf(dtend_datetime, sizeof(dtend_datetime), CAL_FORMAT_LOCAL_DATETIME,
1582                                 event->end.time.date.year,
1583                                 event->end.time.date.month,
1584                                 event->end.time.date.mday,
1585                                 event->end.time.date.hour,
1586                                 event->end.time.date.minute,
1587                                 event->end.time.date.second);
1588                 cal_db_util_stmt_bind_text(stmt, index, dtend_datetime);
1589         }
1590         index++;
1591
1592         if (event->end_tzid)
1593                 cal_db_util_stmt_bind_text(stmt, index, event->end_tzid);
1594         index++;
1595
1596         if (event->recurrence_id)
1597                 cal_db_util_stmt_bind_text(stmt, index, event->recurrence_id);
1598         index++;
1599         if (event->rdate)
1600                 cal_db_util_stmt_bind_text(stmt, index, event->rdate);
1601         index++;
1602         if (event->sync_data1)
1603                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data1);
1604         index++;
1605         if (event->sync_data2)
1606                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data2);
1607         index++;
1608         if (event->sync_data3)
1609                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data3);
1610         index++;
1611         if (event->sync_data4)
1612                 cal_db_util_stmt_bind_text(stmt, index, event->sync_data4);
1613         index++;
1614
1615         ret = cal_db_util_stmt_step(stmt);
1616         sqlite3_finalize(stmt);
1617         if (CALENDAR_ERROR_NONE != ret) {
1618                 /* LCOV_EXCL_START */
1619                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
1620                 return ret;
1621                 /* LCOV_EXCL_STOP */
1622         }
1623
1624         /*
1625          * update parent event changed ver in case this event is exception mod
1626          * which is original_event_id > 0
1627          */
1628         cal_db_event_update_original_event_version(event->original_event_id, input_ver);
1629         cal_db_rrule_get_rrule_from_record(record, &rrule);
1630         cal_db_rrule_update_record(id, rrule);
1631         CAL_FREE(rrule);
1632
1633         cal_db_instance_discard_record(id);
1634         cal_db_instance_publish_record(record);
1635
1636         cal_db_alarm_delete_with_id(id);
1637         cal_db_attendee_delete_with_id(id);
1638         _cal_db_event_exception_delete_with_id(id);
1639         cal_db_extended_delete_with_id(id, CALENDAR_RECORD_TYPE_EVENT);
1640
1641         if (event->alarm_list && 0 < event->alarm_list->count) {
1642                 ret = cal_db_alarm_insert_records(event->alarm_list, event->index);
1643                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_alarm_insert_records() Fail(%x)", ret);
1644         }
1645
1646         if (event->attendee_list && 0 < event->attendee_list->count) {
1647                 ret = cal_db_attendee_insert_records(event->attendee_list, event->index);
1648                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_attendee_insert_records() Fail(%x)", ret);
1649         }
1650
1651         if (event->exception_list && 0 < event->exception_list->count) {
1652                 ret = cal_db_event_insert_records(event->exception_list, id);
1653                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_event_insert_records() Fail(%x)", ret);
1654         }
1655
1656         if (event->extended_list && 0 < event->extended_list->count) {
1657                 ret = cal_db_extended_insert_records(event->extended_list, id, CALENDAR_RECORD_TYPE_EVENT);
1658                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_extended_insert_records() Fail(%d)", ret);
1659         }
1660
1661         cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
1662
1663         return CALENDAR_ERROR_NONE;
1664 }
1665
1666 static void _cal_db_event_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record,
1667                 int *exception, int *extended)
1668 {
1669         cal_event_s *event = NULL;
1670         const unsigned char *temp;
1671         int count = 0;
1672
1673         event = (cal_event_s*)(record);
1674
1675         event->index = sqlite3_column_int(stmt, count++);
1676         sqlite3_column_int(stmt, count++);
1677
1678         temp = sqlite3_column_text(stmt, count++);
1679         event->summary = cal_strdup((const char*)temp);
1680         temp = sqlite3_column_text(stmt, count++);
1681         event->description = cal_strdup((const char*)temp);
1682
1683         temp = sqlite3_column_text(stmt, count++);
1684         event->location = cal_strdup((const char*)temp);
1685
1686         temp = sqlite3_column_text(stmt, count++);
1687         event->categories = cal_strdup((const char*)temp);
1688
1689         temp = sqlite3_column_text(stmt, count++);
1690         event->exdate = cal_strdup((const char*)temp);
1691
1692         event->event_status = sqlite3_column_int(stmt, count++);
1693         event->priority = sqlite3_column_int(stmt, count++);
1694         event->timezone = sqlite3_column_int(stmt, count++);
1695         event->contact_id = sqlite3_column_int(stmt, count++);
1696         event->busy_status = sqlite3_column_int(stmt, count++);
1697         event->sensitivity = sqlite3_column_int(stmt, count++);
1698
1699         temp = sqlite3_column_text(stmt, count++);
1700         event->uid = cal_strdup((const char*)temp);
1701
1702         temp = sqlite3_column_text(stmt, count++);
1703         event->organizer_name = cal_strdup((const char*)temp);
1704
1705         temp = sqlite3_column_text(stmt, count++);
1706         event->organizer_email = cal_strdup((const char*)temp);
1707
1708         event->meeting_status = sqlite3_column_int(stmt, count++);
1709         event->calendar_id = sqlite3_column_int(stmt, count++);
1710         event->original_event_id = sqlite3_column_int(stmt, count++);
1711         event->latitude = sqlite3_column_double(stmt, count++);
1712         event->longitude = sqlite3_column_double(stmt, count++);
1713         event->email_id = sqlite3_column_int(stmt, count++);
1714         event->created_time = sqlite3_column_int64(stmt, count++);
1715
1716         count++; /* completed_time */
1717         count++; /* progress */
1718         count++; /* changed_ver */
1719         count++; /* created_ver */
1720
1721         event->is_deleted = sqlite3_column_int(stmt, count++);
1722         event->start.type = sqlite3_column_int(stmt, count++);
1723
1724         if (event->start.type == CALENDAR_TIME_UTIME) {
1725                 event->start.time.utime = sqlite3_column_int64(stmt, count++);
1726                 count++; /* dtstart_datetime */
1727         } else {
1728                 count++; /* dtstart_utime */
1729                 temp = sqlite3_column_text(stmt, count++);
1730                 if (temp) {
1731                         sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(event->start.time.date.year),
1732                                         &(event->start.time.date.month), &(event->start.time.date.mday),
1733                                         &(event->start.time.date.hour), &(event->start.time.date.minute),
1734                                         &(event->start.time.date.second));
1735                 }
1736         }
1737
1738         temp = sqlite3_column_text(stmt, count++);
1739         event->start_tzid = cal_strdup((const char*)temp);
1740
1741         event->end.type = sqlite3_column_int(stmt, count++);
1742         if (event->end.type == CALENDAR_TIME_UTIME) {
1743                 event->end.time.utime = sqlite3_column_int64(stmt, count++);
1744                 count++; /* dtend_datetime */
1745         } else {
1746                 count++; /* dtend_utime */
1747                 temp = sqlite3_column_text(stmt, count++);
1748                 if (temp) {
1749                         sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(event->end.time.date.year),
1750                                         &(event->end.time.date.month), &(event->end.time.date.mday),
1751                                         &(event->end.time.date.hour), &(event->end.time.date.minute),
1752                                         &(event->end.time.date.second));
1753                 }
1754         }
1755         temp = sqlite3_column_text(stmt, count++);
1756         event->end_tzid = cal_strdup((const char*)temp);
1757
1758         event->last_mod = sqlite3_column_int64(stmt, count++);
1759         sqlite3_column_int(stmt, count++);
1760
1761         temp = sqlite3_column_text(stmt, count++);
1762         event->recurrence_id = cal_strdup((const char*)temp);
1763         temp = sqlite3_column_text(stmt, count++);
1764         event->rdate = cal_strdup((const char*)temp);
1765         event->has_attendee = sqlite3_column_int(stmt, count++);
1766         event->has_alarm = sqlite3_column_int(stmt, count++);
1767         event->system_type = sqlite3_column_int(stmt, count++);
1768         event->updated = sqlite3_column_int(stmt, count++);
1769         temp = sqlite3_column_text(stmt, count++);
1770         event->sync_data1 = cal_strdup((const char*)temp);
1771         temp = sqlite3_column_text(stmt, count++);
1772         event->sync_data2 = cal_strdup((const char*)temp);
1773         temp = sqlite3_column_text(stmt, count++);
1774         event->sync_data3 = cal_strdup((const char*)temp);
1775         temp = sqlite3_column_text(stmt, count++);
1776         event->sync_data4 = cal_strdup((const char*)temp);
1777
1778         /* has_exception */
1779         if (exception)
1780                 *exception = sqlite3_column_int(stmt, count++);
1781
1782         /* has_extended */
1783         if (extended)
1784                 *extended = sqlite3_column_int(stmt, count++);
1785
1786         event->freq = sqlite3_column_int(stmt, count++);
1787         event->is_allday = sqlite3_column_int(stmt, count++);
1788
1789         if (is_view_table == true) {
1790                 if (event->freq <= 0)
1791                         return ;
1792
1793                 event->range_type = sqlite3_column_int(stmt, count++);
1794                 event->until.type = sqlite3_column_int(stmt, count++);
1795
1796                 switch (event->until.type) {
1797                 case CALENDAR_TIME_UTIME:
1798                         event->until.time.utime = sqlite3_column_int64(stmt, count++);
1799                         count++; /* datetime */
1800                         break;
1801
1802                 case CALENDAR_TIME_LOCALTIME:
1803                         count++; /* utime */
1804                         temp = sqlite3_column_text(stmt, count++);
1805                         if (temp) {
1806                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(event->until.time.date.year),
1807                                                 &(event->until.time.date.month), &(event->until.time.date.mday),
1808                                                 &(event->until.time.date.hour), &(event->until.time.date.minute),
1809                                                 &(event->until.time.date.second));
1810                         }
1811                         break;
1812                 }
1813
1814                 event->count = sqlite3_column_int(stmt, count++);
1815                 event->interval = sqlite3_column_int(stmt, count++);
1816
1817                 temp = sqlite3_column_text(stmt, count++);
1818                 event->bysecond = cal_strdup((const char*)temp);
1819
1820                 temp = sqlite3_column_text(stmt, count++);
1821                 event->byminute = cal_strdup((const char*)temp);
1822
1823                 temp = sqlite3_column_text(stmt, count++);
1824                 event->byhour = cal_strdup((const char*)temp);
1825
1826                 temp = sqlite3_column_text(stmt, count++);
1827                 event->byday = cal_strdup((const char*)temp);
1828
1829                 temp = sqlite3_column_text(stmt, count++);
1830                 event->bymonthday = cal_strdup((const char*)temp);
1831
1832                 temp = sqlite3_column_text(stmt, count++);
1833                 event->byyearday = cal_strdup((const char*)temp);
1834
1835                 temp = sqlite3_column_text(stmt, count++);
1836                 event->byweekno = cal_strdup((const char*)temp);
1837
1838                 temp = sqlite3_column_text(stmt, count++);
1839                 event->bymonth = cal_strdup((const char*)temp);
1840
1841                 temp = sqlite3_column_text(stmt, count++);
1842                 event->bysetpos = cal_strdup((const char*)temp);
1843
1844                 event->wkst = sqlite3_column_int(stmt, count++);
1845
1846                 sqlite3_column_int(stmt, count++); /* calendar deleted */
1847         }
1848
1849 }
1850
1851 static void _cal_db_event_get_property_stmt(sqlite3_stmt *stmt,
1852                 unsigned int property, int *stmt_count, calendar_record_h record)
1853 {
1854         cal_event_s *event = NULL;
1855         const unsigned char *temp;
1856
1857         event = (cal_event_s*)(record);
1858
1859         switch (property) {
1860         case CAL_PROPERTY_EVENT_ID:
1861                 event->index = sqlite3_column_int(stmt, *stmt_count);
1862                 break;
1863         case CAL_PROPERTY_EVENT_CALENDAR_ID:
1864                 event->calendar_id = sqlite3_column_int(stmt, *stmt_count);
1865                 break;
1866         case CAL_PROPERTY_EVENT_SUMMARY:
1867                 temp = sqlite3_column_text(stmt, *stmt_count);
1868                 event->summary = cal_strdup((const char*)temp);
1869                 break;
1870         case CAL_PROPERTY_EVENT_DESCRIPTION:
1871                 temp = sqlite3_column_text(stmt, *stmt_count);
1872                 event->description = cal_strdup((const char*)temp);
1873                 break;
1874         case CAL_PROPERTY_EVENT_LOCATION:
1875                 temp = sqlite3_column_text(stmt, *stmt_count);
1876                 event->location = cal_strdup((const char*)temp);
1877                 break;
1878         case CAL_PROPERTY_EVENT_CATEGORIES:
1879                 temp = sqlite3_column_text(stmt, *stmt_count);
1880                 event->categories = cal_strdup((const char*)temp);
1881                 break;
1882         case CAL_PROPERTY_EVENT_EXDATE:
1883                 temp = sqlite3_column_text(stmt, *stmt_count);
1884                 event->exdate = cal_strdup((const char*)temp);
1885                 break;
1886         case CAL_PROPERTY_EVENT_EVENT_STATUS:
1887                 event->event_status = sqlite3_column_int(stmt, *stmt_count);
1888                 break;
1889         case CAL_PROPERTY_EVENT_PRIORITY:
1890                 event->priority = sqlite3_column_int(stmt, *stmt_count);
1891                 break;
1892         case CAL_PROPERTY_EVENT_TIMEZONE:
1893                 event->timezone = sqlite3_column_int(stmt, *stmt_count);
1894                 break;
1895         case CAL_PROPERTY_EVENT_CONTACT_ID:
1896                 event->contact_id = sqlite3_column_int(stmt, *stmt_count);
1897                 break;
1898         case CAL_PROPERTY_EVENT_BUSY_STATUS:
1899                 event->busy_status = sqlite3_column_int(stmt, *stmt_count);
1900                 break;
1901         case CAL_PROPERTY_EVENT_SENSITIVITY:
1902                 event->sensitivity = sqlite3_column_int(stmt, *stmt_count);
1903                 break;
1904         case CAL_PROPERTY_EVENT_UID:
1905                 temp = sqlite3_column_text(stmt, *stmt_count);
1906                 event->uid = cal_strdup((const char*)temp);
1907                 break;
1908         case CAL_PROPERTY_EVENT_ORGANIZER_NAME:
1909                 temp = sqlite3_column_text(stmt, *stmt_count);
1910                 event->organizer_name = cal_strdup((const char*)temp);
1911                 break;
1912         case CAL_PROPERTY_EVENT_ORGANIZER_EMAIL:
1913                 temp = sqlite3_column_text(stmt, *stmt_count);
1914                 event->organizer_email = cal_strdup((const char*)temp);
1915                 break;
1916         case CAL_PROPERTY_EVENT_MEETING_STATUS:
1917                 event->meeting_status = sqlite3_column_int(stmt, *stmt_count);
1918                 break;
1919         case CAL_PROPERTY_EVENT_ORIGINAL_EVENT_ID:
1920                 event->original_event_id = sqlite3_column_int(stmt, *stmt_count);
1921                 break;
1922         case CAL_PROPERTY_EVENT_LATITUDE:
1923                 event->latitude = sqlite3_column_double(stmt, *stmt_count);
1924                 break;
1925         case CAL_PROPERTY_EVENT_LONGITUDE:
1926                 event->longitude = sqlite3_column_double(stmt, *stmt_count);
1927                 break;
1928         case CAL_PROPERTY_EVENT_EMAIL_ID:
1929                 event->email_id = sqlite3_column_int(stmt, *stmt_count);
1930                 break;
1931         case CAL_PROPERTY_EVENT_CREATED_TIME:
1932                 event->created_time = sqlite3_column_int64(stmt, *stmt_count);
1933                 break;
1934         case CAL_PROPERTY_EVENT_LAST_MODIFIED_TIME:
1935                 event->last_mod = sqlite3_column_int64(stmt, *stmt_count);
1936                 break;
1937         case CAL_PROPERTY_EVENT_IS_DELETED:
1938                 event->is_deleted = sqlite3_column_int(stmt, *stmt_count);
1939                 break;
1940         case CAL_PROPERTY_EVENT_FREQ:
1941                 event->freq = sqlite3_column_int(stmt, *stmt_count);
1942                 break;
1943         case CAL_PROPERTY_EVENT_RANGE_TYPE:
1944                 event->range_type = sqlite3_column_int(stmt, *stmt_count);
1945                 break;
1946         case CAL_PROPERTY_EVENT_UNTIL:
1947                 event->until.type = sqlite3_column_int(stmt, *stmt_count);
1948                 if (event->until.type == CALENDAR_TIME_UTIME) {
1949                         *stmt_count = *stmt_count+1;
1950                         event->until.time.utime = sqlite3_column_int64(stmt, *stmt_count);
1951                         *stmt_count = *stmt_count+1; /* until_datetime */
1952                 } else {
1953                         *stmt_count = *stmt_count+1;
1954                         *stmt_count = *stmt_count+1;
1955                         temp = sqlite3_column_text(stmt, *stmt_count);
1956                         if (temp) {
1957                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(event->until.time.date.year),
1958                                                 &(event->until.time.date.month), &(event->until.time.date.mday),
1959                                                 &(event->until.time.date.hour), &(event->until.time.date.minute),
1960                                                 &(event->until.time.date.second));
1961                         }
1962                 }
1963                 break;
1964         case CAL_PROPERTY_EVENT_COUNT:
1965                 event->count = sqlite3_column_int(stmt, *stmt_count);
1966                 break;
1967         case CAL_PROPERTY_EVENT_INTERVAL:
1968                 event->interval = sqlite3_column_int(stmt, *stmt_count);
1969                 break;
1970         case CAL_PROPERTY_EVENT_BYSECOND:
1971                 temp = sqlite3_column_text(stmt, *stmt_count);
1972                 event->bysecond = cal_strdup((const char*)temp);
1973                 break;
1974         case CAL_PROPERTY_EVENT_BYMINUTE:
1975                 temp = sqlite3_column_text(stmt, *stmt_count);
1976                 event->byminute = cal_strdup((const char*)temp);
1977                 break;
1978         case CAL_PROPERTY_EVENT_BYHOUR:
1979                 temp = sqlite3_column_text(stmt, *stmt_count);
1980                 event->byhour = cal_strdup((const char*)temp);
1981                 break;
1982         case CAL_PROPERTY_EVENT_BYDAY:
1983                 temp = sqlite3_column_text(stmt, *stmt_count);
1984                 event->byday = cal_strdup((const char*)temp);
1985                 break;
1986         case CAL_PROPERTY_EVENT_BYMONTHDAY:
1987                 temp = sqlite3_column_text(stmt, *stmt_count);
1988                 event->bymonthday = cal_strdup((const char*)temp);
1989                 break;
1990         case CAL_PROPERTY_EVENT_BYYEARDAY:
1991                 temp = sqlite3_column_text(stmt, *stmt_count);
1992                 event->byyearday = cal_strdup((const char*)temp);
1993                 break;
1994         case CAL_PROPERTY_EVENT_BYWEEKNO:
1995                 temp = sqlite3_column_text(stmt, *stmt_count);
1996                 event->byweekno = cal_strdup((const char*)temp);
1997                 break;
1998         case CAL_PROPERTY_EVENT_BYMONTH:
1999                 temp = sqlite3_column_text(stmt, *stmt_count);
2000                 event->bymonth = cal_strdup((const char*)temp);
2001                 break;
2002         case CAL_PROPERTY_EVENT_BYSETPOS:
2003                 temp = sqlite3_column_text(stmt, *stmt_count);
2004                 event->bysetpos = cal_strdup((const char*)temp);
2005                 break;
2006         case CAL_PROPERTY_EVENT_WKST:
2007                 event->wkst = sqlite3_column_int(stmt, *stmt_count);
2008                 break;
2009         case CAL_PROPERTY_EVENT_RECURRENCE_ID:
2010                 temp = sqlite3_column_text(stmt, *stmt_count);
2011                 event->recurrence_id = cal_strdup((const char*)temp);
2012                 break;
2013         case CAL_PROPERTY_EVENT_RDATE:
2014                 temp = sqlite3_column_text(stmt, *stmt_count);
2015                 event->rdate = cal_strdup((const char*)temp);
2016                 break;
2017         case CAL_PROPERTY_EVENT_HAS_ATTENDEE:
2018                 event->has_attendee = sqlite3_column_int(stmt, *stmt_count);
2019                 break;
2020         case CAL_PROPERTY_EVENT_HAS_ALARM:
2021                 event->has_alarm = sqlite3_column_int(stmt, *stmt_count);
2022                 break;
2023         case CAL_PROPERTY_EVENT_SYNC_DATA1:
2024                 temp = sqlite3_column_text(stmt, *stmt_count);
2025                 event->sync_data1 = cal_strdup((const char*)temp);
2026                 break;
2027         case CAL_PROPERTY_EVENT_SYNC_DATA2:
2028                 temp = sqlite3_column_text(stmt, *stmt_count);
2029                 event->sync_data2 = cal_strdup((const char*)temp);
2030                 break;
2031         case CAL_PROPERTY_EVENT_SYNC_DATA3:
2032                 temp = sqlite3_column_text(stmt, *stmt_count);
2033                 event->sync_data3 = cal_strdup((const char*)temp);
2034                 break;
2035         case CAL_PROPERTY_EVENT_SYNC_DATA4:
2036                 temp = sqlite3_column_text(stmt, *stmt_count);
2037                 event->sync_data4 = cal_strdup((const char*)temp);
2038                 break;
2039         case CAL_PROPERTY_EVENT_START:
2040                 event->start.type = sqlite3_column_int(stmt, *stmt_count);
2041                 if (event->start.type == CALENDAR_TIME_UTIME) {
2042                         *stmt_count = *stmt_count+1;
2043                         event->start.time.utime = sqlite3_column_int64(stmt, *stmt_count);
2044                         *stmt_count = *stmt_count+1; /* dtstart_datetime */
2045                 } else {
2046                         *stmt_count = *stmt_count+1;
2047                         *stmt_count = *stmt_count+1;
2048                         temp = sqlite3_column_text(stmt, *stmt_count);
2049                         if (temp) {
2050                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(event->start.time.date.year),
2051                                                 &(event->start.time.date.month), &(event->start.time.date.mday),
2052                                                 &(event->start.time.date.hour), &(event->start.time.date.minute),
2053                                                 &(event->start.time.date.second));
2054                         }
2055                 }
2056                 break;
2057         case CAL_PROPERTY_EVENT_START_TZID:
2058                 temp = sqlite3_column_text(stmt, *stmt_count);
2059                 event->start_tzid = cal_strdup((const char*)temp);
2060                 break;
2061         case CAL_PROPERTY_EVENT_END:
2062                 event->end.type = sqlite3_column_int(stmt, *stmt_count);
2063                 if (event->end.type == CALENDAR_TIME_UTIME) {
2064                         *stmt_count = *stmt_count+1;
2065                         event->end.time.utime = sqlite3_column_int64(stmt, *stmt_count);
2066                         *stmt_count = *stmt_count+1; /* dtstart_datetime */
2067                 } else {
2068                         *stmt_count = *stmt_count+1; /* dtend_utime */
2069                         *stmt_count = *stmt_count+1;
2070                         temp = sqlite3_column_text(stmt, *stmt_count);
2071                         if (temp) {
2072                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(event->end.time.date.year),
2073                                                 &(event->end.time.date.month), &(event->end.time.date.mday),
2074                                                 &(event->end.time.date.hour), &(event->end.time.date.minute),
2075                                                 &(event->end.time.date.second));
2076                         }
2077                 }
2078                 break;
2079         case CAL_PROPERTY_EVENT_END_TZID:
2080                 temp = sqlite3_column_text(stmt, *stmt_count);
2081                 event->end_tzid = cal_strdup((const char*)temp);
2082                 break;
2083         case CAL_PROPERTY_EVENT_CALENDAR_SYSTEM_TYPE:
2084                 event->system_type = sqlite3_column_int(stmt, *stmt_count);
2085                 break;
2086         case CAL_PROPERTY_EVENT_IS_ALLDAY:
2087                 event->is_allday = sqlite3_column_int(stmt, *stmt_count);
2088                 break;
2089         default:
2090                 /* LCOV_EXCL_START */
2091                 ERR("invalid (0x%x)", property);
2092                 break;
2093                 /* LCOV_EXCL_STOP */
2094         }
2095
2096         *stmt_count = *stmt_count+1;
2097 }
2098
2099 static void _cal_db_event_get_projection_stmt(sqlite3_stmt *stmt,
2100                 const unsigned int *projection, const int projection_count,
2101                 calendar_record_h record)
2102 {
2103         int i = 0;
2104         int stmt_count = 0;
2105
2106         for (i = 0; i < projection_count; i++)
2107                 _cal_db_event_get_property_stmt(stmt, projection[i], &stmt_count, record);
2108 }
2109
2110 static bool _cal_db_event_check_calendar_book_type(calendar_record_h record)
2111 {
2112         int ret = 0;
2113         int store_type = 0;
2114         cal_event_s *event = (cal_event_s *)record;
2115         char query[CAL_DB_SQL_MAX_LEN];
2116         sqlite3_stmt *stmt = NULL;
2117
2118         snprintf(query, sizeof(query), "SELECT store_type FROM %s WHERE id = %d ",
2119                         CAL_TABLE_CALENDAR, event->calendar_id);
2120         ret = cal_db_util_query_prepare(query, &stmt);
2121         if (CALENDAR_ERROR_NONE != ret) {
2122                 /* LCOV_EXCL_START */
2123                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
2124                 SECURE("query[%s]", query);
2125                 return false;
2126                 /* LCOV_EXCL_STOP */
2127         }
2128
2129         if (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
2130                 store_type = sqlite3_column_int(stmt, 0);
2131         } else {
2132                 /* LCOV_EXCL_START */
2133                 ERR("Failed to get calendar: calendar_id(%d)", event->calendar_id);
2134                 sqlite3_finalize(stmt);
2135                 stmt = NULL;
2136                 return false;
2137                 /* LCOV_EXCL_STOP */
2138         }
2139         sqlite3_finalize(stmt);
2140
2141         switch (store_type) {
2142         case CALENDAR_BOOK_TYPE_NONE:
2143         case CALENDAR_BOOK_TYPE_EVENT:
2144                 ret = true;
2145                 break;
2146         case CALENDAR_BOOK_TYPE_TODO:
2147         default:
2148                 ret = false;
2149                 break;
2150         }
2151         return ret;
2152 }
2153
2154 static int _cal_db_event_delete_exception(int *exception_ids, int exception_len)
2155 {
2156         int ret = 0;
2157         char query[CAL_DB_SQL_MAX_LEN] = {0};
2158
2159         int i;
2160         for (i = 0; i < exception_len; i++) {
2161                 snprintf(query, sizeof(query), "DELETE FROM %s WHERE id=%d ", CAL_TABLE_SCHEDULE, exception_ids[i]);
2162                 ret = cal_db_util_query_exec(query);
2163                 if (CALENDAR_ERROR_NONE != ret) {
2164                         /* LCOV_EXCL_START */
2165                         ERR("cal_db_util_query_exec() Fail(%d)", ret);
2166                         SECURE("[%s]", query);
2167                         return ret;
2168                         /* LCOV_EXCL_STOP */
2169                 }
2170         }
2171         return CALENDAR_ERROR_NONE;
2172 }
2173
2174 static int _cal_db_event_update_dirty(calendar_record_h record, int is_dirty_in_time)
2175 {
2176         int event_id = 0;
2177         int ret = CALENDAR_ERROR_NONE;
2178         calendar_record_h original_record = NULL;
2179
2180         ret = calendar_record_get_int(record, _calendar_event.id, &event_id);
2181         RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
2182
2183         DBG("id=%d", event_id);
2184
2185         ret = _cal_db_event_get_record(event_id, &original_record);
2186         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "_cal_db_event_get_record() Fail(%d)", ret);
2187
2188         cal_record_s *_record = NULL;
2189         const cal_property_info_s* property_info = NULL;
2190         int property_info_count = 0;
2191         int i = 0;
2192
2193         _record = (cal_record_s *)record;
2194
2195         property_info = cal_view_get_property_info(_record->view_uri, &property_info_count);
2196
2197         for (i = 0; i < property_info_count; i++) {
2198                 if (false == cal_record_check_property_flag(record, property_info[i].property_id , CAL_PROPERTY_FLAG_DIRTY))
2199                         continue;
2200
2201                 if (property_info[i].property_id == CAL_PROPERTY_EVENT_EXDATE) {
2202                         int calendar_id = 0;
2203                         int account_id = 0;
2204                         calendar_book_sync_event_type_e sync_event_type = CALENDAR_BOOK_SYNC_EVENT_FOR_ME;
2205
2206                         char *record_exdate = NULL;
2207                         ret = calendar_record_get_str_p(record, property_info[i]. property_id, &record_exdate);
2208                         if (CALENDAR_ERROR_NONE != ret)
2209                                 continue;
2210                         ret = calendar_record_get_int(original_record, CAL_PROPERTY_EVENT_CALENDAR_ID, &calendar_id);
2211                         if (CALENDAR_ERROR_NONE != ret)
2212                                 continue;
2213
2214                         calendar_record_h record_calendar = NULL;
2215                         ret = cal_db_get_record(_calendar_book._uri, calendar_id, &record_calendar);
2216                         ret |= calendar_record_get_int(record_calendar, _calendar_book.account_id, &account_id);
2217                         ret |= calendar_record_get_int(record_calendar, _calendar_book.sync_event, (int *)&sync_event_type);
2218                         DBG("calendar_id(%d), account_id(%d), sync_event(%d)", calendar_id, account_id, sync_event_type);
2219                         calendar_record_destroy(record_calendar, true);
2220
2221                         char *original_exdate = NULL;
2222                         ret = calendar_record_get_str_p(original_record, property_info[i].property_id, &original_exdate);
2223                         if (CALENDAR_ERROR_NONE != ret)
2224                                 continue;
2225                         if (sync_event_type == CALENDAR_BOOK_SYNC_EVENT_FOR_EVERY_AND_REMAIN) {
2226                                 ret = _cal_db_event_exdate_insert_normal(event_id, original_exdate,
2227                                                 record_exdate, NULL, NULL);
2228                                 WARN_IF(CALENDAR_ERROR_NONE != ret, "%s->%s", original_exdate, record_exdate);
2229
2230                         } else {
2231                                 int *exception_ids = NULL;
2232                                 int exception_len = 0;
2233                                 ret = _cal_db_event_exdate_insert_normal(event_id, original_exdate,
2234                                                 record_exdate, &exception_ids, &exception_len);
2235                                 WARN_IF(CALENDAR_ERROR_NONE != ret, "%s->%s", original_exdate, record_exdate);
2236                                 ret = _cal_db_event_delete_exception(exception_ids, exception_len);
2237                                 WARN_IF(CALENDAR_ERROR_NONE != ret, "_cal_db_event_delete_record() Fail");
2238                                 free(exception_ids);
2239                         }
2240                         ret = cal_record_set_str(original_record, property_info[i].property_id, record_exdate);
2241                         if (CALENDAR_ERROR_NONE != ret)
2242                                 continue;
2243                 } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_INT) == true) {
2244                         int tmp = 0;
2245                         ret = calendar_record_get_int(record, property_info[i].property_id, &tmp);
2246                         if (CALENDAR_ERROR_NONE != ret)
2247                                 continue;
2248                         ret = cal_record_set_int(original_record, property_info[i].property_id, tmp);
2249                         if (CALENDAR_ERROR_NONE != ret)
2250                                 continue;
2251                 } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_STR) == true) {
2252                         char *tmp = NULL;
2253                         ret = calendar_record_get_str_p(record, property_info[i].property_id, &tmp);
2254                         if (CALENDAR_ERROR_NONE != ret)
2255                                 continue;
2256                         ret = cal_record_set_str(original_record, property_info[i].property_id, tmp);
2257                         if (CALENDAR_ERROR_NONE != ret)
2258                                 continue;
2259                 } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_DOUBLE) == true) {
2260                         double tmp = 0;
2261                         ret = calendar_record_get_double(record, property_info[i].property_id, &tmp);
2262                         if (CALENDAR_ERROR_NONE != ret)
2263                                 continue;
2264                         ret = cal_record_set_double(original_record, property_info[i].property_id, tmp);
2265                         if (CALENDAR_ERROR_NONE != ret)
2266                                 continue;
2267                 } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_LLI) == true) {
2268                         long long int tmp = 0;
2269                         ret = calendar_record_get_lli(record, property_info[i].property_id, &tmp);
2270                         if (CALENDAR_ERROR_NONE != ret)
2271                                 continue;
2272                         ret = cal_record_set_lli(original_record, property_info[i].property_id, tmp);
2273                         if (CALENDAR_ERROR_NONE != ret)
2274                                 continue;
2275                 } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true) {
2276                         calendar_time_s tmp = {0,};
2277                         ret = calendar_record_get_caltime(record, property_info[i].property_id, &tmp);
2278                         if (CALENDAR_ERROR_NONE != ret)
2279                                 continue;
2280                         ret = cal_record_set_caltime(original_record, property_info[i].property_id, tmp);
2281                         if (CALENDAR_ERROR_NONE != ret)
2282                                 continue;
2283                 }
2284         }
2285         /* child replace */
2286         cal_event_s *tmp = (cal_event_s *)original_record;
2287         cal_event_s *tmp_src = (cal_event_s *)record;
2288
2289         if (tmp->alarm_list)
2290                 calendar_list_destroy((calendar_list_h)tmp->alarm_list, true);
2291         cal_list_clone((calendar_list_h)tmp_src->alarm_list, (calendar_list_h *)&tmp->alarm_list);
2292
2293         if (tmp->attendee_list)
2294                 calendar_list_destroy((calendar_list_h)tmp->attendee_list, true);
2295         cal_list_clone((calendar_list_h)tmp_src->attendee_list, (calendar_list_h *)&tmp->attendee_list);
2296
2297         if (tmp->exception_list)
2298                 calendar_list_destroy((calendar_list_h)tmp->exception_list, true);
2299         cal_list_clone((calendar_list_h)tmp_src->exception_list, (calendar_list_h *)&tmp->exception_list);
2300
2301         if (tmp->extended_list)
2302                 calendar_list_destroy((calendar_list_h)tmp->extended_list, true);
2303         cal_list_clone((calendar_list_h)tmp_src->extended_list, (calendar_list_h *)&tmp->extended_list);
2304
2305         CAL_RECORD_RESET_COMMON((cal_record_s*)original_record);
2306         ret = __update_record(original_record, is_dirty_in_time);
2307         calendar_record_destroy(original_record, true);
2308
2309         return ret;
2310 }
2311
2312 static int _cal_db_event_exception_get_records(int original_id, cal_list_s *list)
2313 {
2314         int ret;
2315         char query[CAL_DB_SQL_MAX_LEN] = {0};
2316         sqlite3_stmt *stmt = NULL;
2317
2318         RETVM_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER,
2319                         "Invalid parameter: list is NULL");
2320
2321         snprintf(query, sizeof(query),
2322                         "SELECT "CAL_QUERY_SCHEDULE_A_ALL" FROM %s AS A "
2323                         "WHERE original_event_id = %d AND is_deleted = 0 ",
2324                         CAL_TABLE_SCHEDULE,
2325                         original_id);
2326
2327         ret = cal_db_util_query_prepare(query, &stmt);
2328         if (CALENDAR_ERROR_NONE != ret) {
2329                 /* LCOV_EXCL_START */
2330                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
2331                 SECURE("query[%s]", query);
2332                 return ret;
2333                 /* LCOV_EXCL_STOP */
2334         }
2335
2336         calendar_record_h record = NULL;
2337
2338         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
2339                 int exception = 0, extended = 0;
2340                 ret = calendar_record_create(_calendar_event._uri, &record);
2341                 if (CALENDAR_ERROR_NONE != ret) {
2342                         /* LCOV_EXCL_START */
2343                         ERR("calendar_record_create() Fail(%d)", ret);
2344                         sqlite3_finalize(stmt);
2345                         cal_list_clear(list);
2346                         return ret;
2347                         /* LCOV_EXCL_STOP */
2348                 }
2349
2350                 _cal_db_event_get_stmt(stmt, false, record, &exception, &extended);
2351
2352                 cal_rrule_s *rrule = NULL;
2353                 cal_event_s *event = (cal_event_s *)record;
2354                 if (CALENDAR_RECURRENCE_NONE != event->freq) {
2355                         ret = cal_db_rrule_get_rrule(event->index, &rrule);
2356                         if (CALENDAR_ERROR_NONE == ret) {
2357                                 cal_db_rrule_set_rrule_to_record(rrule, record);
2358                                 CAL_FREE(rrule);
2359                         }
2360                 }
2361
2362                 if (event->has_alarm == 1)
2363                         cal_db_alarm_get_records(event->index, event->alarm_list);
2364
2365                 if (event->has_attendee == 1)
2366                         cal_db_attendee_get_records(event->index, event->attendee_list);
2367
2368                 if (exception == 1)
2369                         _cal_db_event_exception_get_records(event->index, event->exception_list);
2370
2371                 if (extended == 1)
2372                         cal_db_extended_get_records(event->index, CALENDAR_RECORD_TYPE_EVENT, event->extended_list);
2373
2374                 event->has_alarm = 0;
2375                 if (event->alarm_list && 0 < event->alarm_list->count)
2376                         event->has_alarm = 1;
2377
2378                 event->has_attendee = 0;
2379                 if (event->attendee_list && 0 < event->attendee_list->count)
2380                         event->has_attendee = 1;
2381
2382                 calendar_list_add((calendar_list_h)list, record);
2383         }
2384         sqlite3_finalize(stmt);
2385         return CALENDAR_ERROR_NONE;
2386 }
2387
2388 static int _cal_db_event_exception_delete_with_id(int original_id)
2389 {
2390         int ret = 0;
2391         char query[CAL_DB_SQL_MAX_LEN] = {0};
2392
2393         DBG("delete exception mod with original event id(%d)", original_id);
2394         snprintf(query, sizeof(query), "DELETE FROM %s WHERE original_event_id=%d ",
2395                         CAL_TABLE_SCHEDULE, original_id);
2396         ret = cal_db_util_query_exec(query);
2397         if (CALENDAR_ERROR_NONE != ret) {
2398                 /* LCOV_EXCL_START */
2399                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
2400                 SECURE("[%s]", query);
2401                 return ret;
2402                 /* LCOV_EXCL_STOP */
2403         }
2404
2405         return CALENDAR_ERROR_NONE;
2406 }
2407
2408 static int _cal_db_event_exception_get_ids(int original_id, GList **out_list)
2409 {
2410         int ret = 0;
2411         char query[CAL_DB_SQL_MAX_LEN] = {0};
2412         sqlite3_stmt *stmt = NULL;
2413         GList *list = NULL;
2414
2415         RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
2416
2417         snprintf(query, sizeof(query), "SELECT id FROM %s WHERE original_event_id = %d AND is_deleted = 0 ",
2418                         CAL_TABLE_SCHEDULE, original_id);
2419
2420         ret = cal_db_util_query_prepare(query, &stmt);
2421         if (CALENDAR_ERROR_NONE != ret) {
2422                 /* LCOV_EXCL_START */
2423                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
2424                 SECURE("query[%s]", query);
2425                 return ret;
2426                 /* LCOV_EXCL_STOP */
2427         }
2428
2429         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
2430                 int id = 0;
2431                 id = sqlite3_column_int(stmt, 0);
2432                 list = g_list_append(list, GINT_TO_POINTER(id));
2433
2434         }
2435         sqlite3_finalize(stmt);
2436
2437         *out_list = list;
2438         return CALENDAR_ERROR_NONE;
2439 }
2440
2441 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)
2442 {
2443         int count = 0;
2444         int ret = CALENDAR_ERROR_NONE;
2445         calendar_record_h exception = NULL;
2446         calendar_list_h exception_list = (calendar_list_h)exception_list_s;
2447         GList *id_list = NULL;
2448
2449         _cal_db_event_exception_get_ids(original_id, &id_list);
2450
2451         if (exception_list) {
2452                 calendar_list_get_count(exception_list, &count);
2453                 calendar_list_first(exception_list);
2454                 while (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(exception_list, &exception)) {
2455                         int exception_id = 0;
2456                         ret = calendar_record_get_int(exception, _calendar_event.id, &exception_id);
2457                         DBG("exception(%d)", exception_id);
2458                         if (0 < exception_id && exception_id != original_id) { /* update */
2459                                 bool bchanged = false;
2460                                 cal_record_s *_record = NULL;
2461                                 const cal_property_info_s* property_info = NULL;
2462                                 int property_info_count = 0;
2463
2464                                 _record = (cal_record_s *)exception;
2465
2466                                 property_info = cal_view_get_property_info(_record->view_uri, &property_info_count);
2467
2468                                 /* check updated */
2469                                 int i;
2470                                 for (i = 0; i < property_info_count; i++) {
2471                                         if (true == cal_record_check_property_flag(exception, property_info[i].property_id , CAL_PROPERTY_FLAG_DIRTY)) {
2472                                                 bchanged = true;
2473                                                 break;
2474                                         }
2475                                 }
2476
2477                                 if (bchanged == true || DIRTY_IN_TIME == is_dirty_in_time) {
2478                                         /* update */
2479                                         __update_recurrence_id(exception, old_type, new_type, time_diff);
2480                                         ret = _cal_db_event_update_record(exception);
2481                                         cal_db_instance_discard_record(exception_id);
2482                                         cal_db_instance_publish_record(exception);
2483
2484                                 } else {
2485                                         cal_db_instance_discard_record(exception_id);
2486                                         cal_db_instance_publish_record(exception);
2487                                         DBG("exception don't changed. exception_id=[%d]", exception_id);
2488                                 }
2489
2490                                 if (id_list)
2491                                         id_list = g_list_remove(id_list, GINT_TO_POINTER(exception_id));
2492
2493                         } else {
2494                                 /* insert */
2495                                 ret = cal_record_set_int(exception, _calendar_event.calendar_book_id, calendar_id);
2496                                 if (CALENDAR_ERROR_NONE != ret) {
2497                                         /* LCOV_EXCL_START */
2498                                         ERR("cal_record_set_int() Fail(%d)", ret);
2499                                         if (id_list)
2500                                                 g_list_free(id_list);
2501                                         return ret;
2502                                         /* LCOV_EXCL_STOP */
2503                                 }
2504                                 ret = cal_db_event_insert_record(exception, original_id, NULL);
2505                                 if (CALENDAR_ERROR_NONE != ret) {
2506                                         /* LCOV_EXCL_START */
2507                                         ERR("cal_db_event_insert_record() Fail(%d)", ret);
2508                                         if (id_list)
2509                                                 g_list_free(id_list);
2510                                         return ret;
2511                                         /* LCOV_EXCL_STOP */
2512                                 }
2513                         }
2514                         calendar_list_next(exception_list);
2515                 }
2516         }
2517
2518         if (id_list) {
2519                 GList * tmp_list = g_list_first(id_list);
2520                 while (tmp_list) {
2521                         int tmp = GPOINTER_TO_INT(tmp_list->data);
2522                         char query[CAL_DB_SQL_MAX_LEN] = {0};
2523
2524                         snprintf(query, sizeof(query), "DELETE FROM %s WHERE id=%d ", CAL_TABLE_SCHEDULE, tmp);
2525                         ret = cal_db_util_query_exec(query);
2526                         if (CALENDAR_ERROR_NONE != ret) {
2527                                 /* LCOV_EXCL_START */
2528                                 WARN("cal_db_util_query_exec() Fail(%d)", ret);
2529                                 SECURE("[%s]", query);
2530                                 /* LCOV_EXCL_STOP */
2531                         }
2532                         tmp_list = g_list_next(tmp_list);
2533                 }
2534                 g_list_free(id_list);
2535         }
2536         return CALENDAR_ERROR_NONE;
2537 }
2538
2539 static int _cal_db_event_get_deleted_data(int id, int* book_id, int* created_ver,
2540                 int* original_event_id, char** recurrence_id)
2541 {
2542         int ret = 0;
2543         char query[CAL_DB_SQL_MAX_LEN] = {0};
2544         sqlite3_stmt *stmt = NULL;
2545
2546         RETV_IF(NULL == book_id, CALENDAR_ERROR_INVALID_PARAMETER);
2547         RETV_IF(NULL == created_ver, CALENDAR_ERROR_INVALID_PARAMETER);
2548         RETV_IF(NULL == original_event_id, CALENDAR_ERROR_INVALID_PARAMETER);
2549         RETV_IF(NULL == recurrence_id, CALENDAR_ERROR_INVALID_PARAMETER);
2550
2551         snprintf(query, sizeof(query), "SELECT calendar_id, created_ver, "
2552                         "original_event_id, recurrence_id FROM %s WHERE id = %d ",
2553                         CAL_TABLE_SCHEDULE, id);
2554         ret = cal_db_util_query_prepare(query, &stmt);
2555         if (CALENDAR_ERROR_NONE != ret) {
2556                 /* LCOV_EXCL_START */
2557                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
2558                 SECURE("query[%s]", query);
2559                 return ret;
2560                 /* LCOV_EXCL_STOP */
2561         }
2562
2563         ret = cal_db_util_stmt_step(stmt);
2564         if (CAL_SQLITE_ROW != ret) {
2565                 /* LCOV_EXCL_START */
2566                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
2567                 SECURE("query[%s]", query);
2568                 sqlite3_finalize(stmt);
2569                 return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
2570                 /* LCOV_EXCL_STOP */
2571         }
2572
2573         *book_id = sqlite3_column_int(stmt, 0);
2574         *created_ver = sqlite3_column_int(stmt, 1);
2575         *original_event_id = sqlite3_column_int(stmt, 2);
2576         *recurrence_id = cal_strdup((const char *)sqlite3_column_text(stmt, 3));
2577
2578         sqlite3_finalize(stmt);
2579         return CALENDAR_ERROR_NONE;
2580 }
2581
2582 static int _cal_db_event_exdate_insert_normal(int event_id, const char* original_exdate,
2583                 const char* exdate, int **exception_ids, int *exception_len)
2584 {
2585         int ret = CALENDAR_ERROR_NONE;
2586         gchar **patterns1 = NULL;
2587         gchar **patterns2 = NULL;
2588         int len1 = 0, len2 = 0, i = 0, j = 0;
2589
2590         int input_ver = cal_db_util_get_next_ver();
2591         if (exdate != NULL && 0 < strlen(exdate)) {
2592                 patterns1 = g_strsplit_set(exdate, " ,", -1);
2593                 len1 = g_strv_length(patterns1);
2594         }
2595         if (original_exdate && 0 < strlen(original_exdate)) {
2596                 patterns2 = g_strsplit_set(original_exdate, " ,", -1);
2597                 len2 = g_strv_length(patterns2);
2598         }
2599
2600         int *ids = calloc(len1, sizeof(int));
2601         RETVM_IF(NULL == ids, CALENDAR_ERROR_OUT_OF_MEMORY, "calloc() Fail");
2602
2603         int exception_count = 0;
2604         for (i = 0; i < len1; i++) {
2605                 if (NULL == patterns1[i]) {
2606                         WARN("exdate is NULL, so check next");
2607                         continue;
2608                 }
2609                 bool bFind = false;
2610                 for (j = 0; j < len2; j++) {
2611                         if (NULL == patterns2[j]) {
2612                                 WARN("original exdate is NULL");
2613                                 continue;
2614                         }
2615                         if (CAL_STRING_EQUAL == strcmp(patterns1[i], patterns2[j])) {
2616                                 bFind = true;
2617                                 break;
2618                         }
2619                 }
2620                 if (bFind == false) {
2621                         char query[CAL_DB_SQL_MAX_LEN] = {0};
2622                         long long int start_utime = 0;
2623                         char datetime[16] = {0};
2624                         if (strlen("YYYYMMDD") < strlen(patterns1[i])) {
2625                                 int y, mon, d, h, min, s;
2626                                 sscanf(patterns1[i], CAL_DATETIME_FORMAT_YYYYMMDDTHHMMSSZ,
2627                                                 &y, &mon, &d, &h, &min, &s);
2628                                 start_utime = cal_time_convert_itol(NULL, y, mon, d, h, min, s);
2629
2630                         } else {
2631                                 snprintf(datetime, sizeof(datetime),
2632                                                 "%s", patterns1[i]);
2633
2634                         }
2635                         snprintf(query, sizeof(query),
2636                                         "INSERT INTO %s ("
2637                                         "type, "
2638                                         "created_ver, changed_ver, "
2639                                         "calendar_id, "
2640                                         "original_event_id, "
2641                                         "recurrence_id, "
2642                                         "is_deleted, "
2643                                         "dtstart_type, "
2644                                         "dtstart_utime, "
2645                                         "dtstart_datetime, "
2646                                         "dtstart_tzid, "
2647                                         "dtend_type, "
2648                                         "dtend_utime, "
2649                                         "dtend_datetime, "
2650                                         "dtend_tzid"
2651                                         ") SELECT %d,"
2652                                         "created_ver, %d, "
2653                                         "calendar_id, "
2654                                         "%d, "
2655                                         "'%s', "
2656                                         "1, "
2657                                         "dtstart_type, "
2658                                         "%lld, "
2659                                         "'%s', "
2660                                         "dtstart_tzid, "
2661                                         "dtend_type, "
2662                                         "%lld+(dtend_utime-dtstart_utime), "
2663                                         "'%s', "
2664                                         "dtend_tzid "
2665                                         "FROM %s "
2666                                         "WHERE id = %d; ",
2667                                 CAL_TABLE_SCHEDULE,
2668                                 CAL_SCH_TYPE_EVENT,
2669                                 input_ver,
2670                                 event_id,
2671                                 patterns1[i],
2672                                 start_utime,
2673                                 datetime,
2674                                 start_utime,
2675                                 datetime,
2676                                 CAL_TABLE_SCHEDULE,
2677                                 event_id
2678                                         );
2679                         ret = cal_db_util_query_exec(query);
2680                         if (CALENDAR_ERROR_NONE != ret) {
2681                                 /* LCOV_EXCL_START */
2682                                 WARN("cal_db_util_query_exec() Fail(%d)", ret);
2683                                 SECURE("[%s]", query);
2684                                 /* LCOV_EXCL_STOP */
2685                         }
2686                         int event_id = cal_db_util_last_insert_id();
2687                         DBG("last id(%d)", event_id);
2688                         ids[exception_count] = event_id;
2689                         exception_count++;
2690                 }
2691         }
2692         if (exception_ids)
2693                 *exception_ids = ids;
2694         else
2695                 free(ids);
2696
2697         if (exception_len)
2698                 *exception_len = exception_count;
2699
2700         g_strfreev(patterns1);
2701         g_strfreev(patterns2);
2702         return ret;
2703 }