add comment LCOV_EXCL
[platform/core/pim/calendar-service.git] / server / db / cal_db.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 <unistd.h>
21 #include <glib.h>
22 #include <db-util.h>
23
24 #include "calendar_db.h"
25 #include "calendar_vcalendar.h"
26 #include "cal_internal.h"
27 #include "cal_typedef.h"
28 #include "cal_view.h"
29 #include "cal_record.h"
30 #include "cal_db_util.h"
31 #include "cal_list.h"
32 #include "cal_db.h"
33 #include "cal_access_control.h"
34 #include "cal_utils.h"
35
36 #define BULK_DEFAULT_COUNT 100
37
38 /*
39  * Declear DB plugin
40  */
41 extern cal_db_plugin_cb_s cal_db_calendar_plugin_cb;
42 extern cal_db_plugin_cb_s cal_db_event_plugin_cb;
43 extern cal_db_plugin_cb_s cal_db_instance_normal_plugin_cb;
44 extern cal_db_plugin_cb_s cal_db_instance_normal_extended_plugin_cb;
45 extern cal_db_plugin_cb_s cal_db_instance_allday_plugin_cb;
46 extern cal_db_plugin_cb_s cal_db_instance_allday_extended_plugin_cb;
47 extern cal_db_plugin_cb_s cal_db_todo_plugin_cb;
48 extern cal_db_plugin_cb_s cal_db_alarm_plugin_cb;
49 extern cal_db_plugin_cb_s cal_db_attendee_plugin_cb;
50 extern cal_db_plugin_cb_s cal_db_search_plugin_cb;
51 extern cal_db_plugin_cb_s cal_db_timezone_plugin_cb;
52 extern cal_db_plugin_cb_s cal_db_extended_plugin_cb;
53
54 int cal_db_append_string(char **dst, const char *src)
55 {
56         RETV_IF(NULL == dst, CALENDAR_ERROR_INVALID_PARAMETER);
57         RETV_IF(NULL == src, CALENDAR_ERROR_INVALID_PARAMETER);
58
59         int len_src = strlen(src);
60         if (len_src == 0) {
61                 DBG("src len is 0");
62                 return CALENDAR_ERROR_NONE;
63         }
64         if (NULL == *dst) {
65                 *dst = cal_strdup(src);
66                 if (NULL == *dst) {
67                         /* LCOV_EXCL_START */
68                         ERR("cal_strdup() Fail");
69                         return CALENDAR_ERROR_OUT_OF_MEMORY;
70                         /* LCOV_EXCL_STOP */
71                 }
72                 return CALENDAR_ERROR_NONE;
73         }
74
75         int len_dst = strlen(*dst);
76         char *tmp = *dst;
77         tmp = (char *)realloc(tmp, len_dst + len_src + 2);
78         if (NULL == tmp) {
79                 /* LCOV_EXCL_START */
80                 ERR("realloc() Fail");
81                 return CALENDAR_ERROR_OUT_OF_MEMORY;
82                 /* LCOV_EXCL_STOP */
83         }
84         *dst = tmp;
85         snprintf(*dst + len_dst, len_src + 2, " %s", src);
86
87         return CALENDAR_ERROR_NONE;
88 }
89
90 cal_db_plugin_cb_s* _cal_db_get_plugin(cal_record_type_e type)
91 {
92         switch (type) {
93         case CAL_RECORD_TYPE_CALENDAR:
94                 return (&cal_db_calendar_plugin_cb);
95         case CAL_RECORD_TYPE_EVENT:
96                 return (&cal_db_event_plugin_cb);
97         case CAL_RECORD_TYPE_TODO:
98                 return (&cal_db_todo_plugin_cb);
99         case CAL_RECORD_TYPE_ALARM:
100                 return (&cal_db_alarm_plugin_cb);
101         case CAL_RECORD_TYPE_ATTENDEE:
102                 return (&cal_db_attendee_plugin_cb);
103         case CAL_RECORD_TYPE_TIMEZONE:
104                 return (&cal_db_timezone_plugin_cb);
105         case CAL_RECORD_TYPE_INSTANCE_NORMAL:
106                 return (&cal_db_instance_normal_plugin_cb);
107         case CAL_RECORD_TYPE_INSTANCE_ALLDAY:
108                 return (&cal_db_instance_allday_plugin_cb);
109         case CAL_RECORD_TYPE_INSTANCE_NORMAL_EXTENDED:
110                 return (&cal_db_instance_normal_extended_plugin_cb);
111         case CAL_RECORD_TYPE_INSTANCE_ALLDAY_EXTENDED:
112                 return (&cal_db_instance_allday_extended_plugin_cb);
113         case CAL_RECORD_TYPE_SEARCH:
114                 return (&cal_db_search_plugin_cb);
115         case CAL_RECORD_TYPE_EXTENDED:
116                 return (&cal_db_extended_plugin_cb);
117         default:
118                 /* LCOV_EXCL_START */
119                 ERR("Invalid plugin(%d)", type);
120                 return NULL;
121                 /* LCOV_EXCL_STOP */
122         }
123         return NULL;
124 }
125
126 void cal_db_initialize_view_table(void)
127 {
128         CAL_FN_CALL();
129
130         int ret = CALENDAR_ERROR_NONE;
131         char query[CAL_DB_SQL_MAX_LEN] = {0};
132
133         ret = cal_db_util_begin_trans();
134         RETM_IF(CALENDAR_ERROR_NONE != ret, "cal_db_util_begin_trans() Fail");
135
136         /*
137          * CAL_VIEW_TABLE_EVENT
138          * schedule_table(type=1) + rrule_table
139          * A : schedule_table
140          * B : rrule_table
141          * C : calendar_table
142          */
143         snprintf(query, sizeof(query),
144                         "CREATE VIEW IF NOT EXISTS %s AS "
145                         "SELECT "CAL_QUERY_SCHEDULE_A_ALL", "
146                         "B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
147                         "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
148                         "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst, C.deleted "
149                         "FROM %s as A "
150                         "LEFT OUTER JOIN %s B ON A.id = B.event_id "
151                         "JOIN %s C ON A.calendar_id = C.id "
152                         "WHERE A.type = %d AND A.is_deleted=0 "
153                         "AND C.deleted = 0 ",
154                         CAL_VIEW_TABLE_EVENT,
155                         CAL_TABLE_SCHEDULE,
156                         CAL_TABLE_RRULE,
157                         CAL_TABLE_CALENDAR,
158                         CAL_SCH_TYPE_EVENT);
159         ret = cal_db_util_query_exec(query);
160         if (CALENDAR_ERROR_NONE != ret) {
161                 /* LCOV_EXCL_START */
162                 SECURE("[%s]", query);
163                 ERR("create view Fail");
164                 /* LCOV_EXCL_STOP */
165         }
166
167         /*
168          * CAL_VIEW_TABLE_TODO
169          * schedule_table(type=2) + rrule_table
170          * A : schedule_table
171          * B : rrule_table
172          * C : calendar_table
173          */
174         snprintf(query, sizeof(query),
175                         "CREATE VIEW IF NOT EXISTS %s AS "
176                         "SELECT "CAL_QUERY_SCHEDULE_A_ALL", "
177                         "B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
178                         "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
179                         "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst, C.deleted "
180                         "FROM %s as A "
181                         "LEFT OUTER JOIN %s B ON A.id = B.event_id "
182                         "JOIN %s C ON A.calendar_id = C.id "
183                         "WHERE A.type = %d AND A.is_deleted=0 "
184                         "AND C.deleted = 0 ",
185                         CAL_VIEW_TABLE_TODO,
186                         CAL_TABLE_SCHEDULE,
187                         CAL_TABLE_RRULE,
188                         CAL_TABLE_CALENDAR,
189                         CAL_SCH_TYPE_TODO);
190         ret = cal_db_util_query_exec(query);
191         if (CALENDAR_ERROR_NONE != ret) {
192                 /* LCOV_EXCL_START */
193                 SECURE("[%s]", query);
194                 ERR("create view Fail");
195                 /* LCOV_EXCL_STOP */
196         }
197
198         /*
199          * CAL_VIEW_TABLE_NORMAL_INSTANCE  : CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR
200          * normal_instance_table + schedule_table(type=1) + calendar_table
201          * A = normal_instace_table
202          * B = schedule_table
203          * C = calendar_table
204          */
205         snprintf(query, sizeof(query),
206                         "CREATE VIEW IF NOT EXISTS %s AS SELECT A.event_id, "
207                         "B.dtstart_type, A.dtstart_utime, B.dtstart_datetime, "
208                         "B.dtend_type, A.dtend_utime, B.dtend_datetime, "
209                         "B.summary, B.description, "
210                         "B.location, B.busy_status, B.task_status, B.priority, B.sensitivity, "
211                         "B.rrule_id, B.latitude, B.longitude, B.has_alarm, B.original_event_id, "
212                         "B.calendar_id, B.last_mod, "
213                         "B.sync_data1, "
214                         "C.visibility, C.account_id "
215                         "FROM %s as A, %s as B, %s as C "
216                         "ON A.event_id = B.id AND B.calendar_id = C.id "
217                         "where C.deleted = 0 AND B.is_deleted = 0 ",
218                         CAL_VIEW_TABLE_NORMAL_INSTANCE,
219                         CAL_TABLE_NORMAL_INSTANCE,
220                         CAL_TABLE_SCHEDULE,
221                         CAL_TABLE_CALENDAR);
222         ret = cal_db_util_query_exec(query);
223         if (CALENDAR_ERROR_NONE != ret) {
224                 /* LCOV_EXCL_START */
225                 SECURE("[%s]", query);
226                 ERR("create view Fail");
227                 /* LCOV_EXCL_STOP */
228         }
229
230         /* CAL_VIEW_TABLE_ALLDAY_INSTANCE  : CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR */
231         snprintf(query, sizeof(query),
232                         "CREATE VIEW IF NOT EXISTS %s AS SELECT A.event_id, "
233                         "B.dtstart_type, B.dtstart_utime, A.dtstart_datetime, "
234                         "B.dtend_type, B.dtend_utime, A.dtend_datetime, "
235                         "B.summary, B.description, "
236                         "B.location, B.busy_status, B.task_status, B.priority, B.sensitivity, "
237                         "B.rrule_id, B.latitude, B.longitude, B.has_alarm, B.original_event_id, "
238                         "B.calendar_id, B.last_mod, "
239                         "B.sync_data1, B.is_allday, "
240                         "C.visibility, C.account_id "
241                         "FROM %s as A, %s as B, %s as C "
242                         "ON A.event_id = B.id AND B.calendar_id = C.id "
243                         "where C.deleted = 0 AND B.is_deleted = 0 ",
244                         CAL_VIEW_TABLE_ALLDAY_INSTANCE,
245                         CAL_TABLE_ALLDAY_INSTANCE,
246                         CAL_TABLE_SCHEDULE,
247                         CAL_TABLE_CALENDAR);
248         ret = cal_db_util_query_exec(query);
249         if (CALENDAR_ERROR_NONE != ret) {
250                 /* LCOV_EXCL_START */
251                 SECURE("[%s]", query);
252                 ERR("create view Fail");
253                 /* LCOV_EXCL_STOP */
254         }
255
256         /*
257          * CAL_VIEW_TABLE_NORMAL_INSTANCE_EXTENDED  : CALENDAR_VIEW_INSTANCE_NORMAL_CALENDAR_EXTENDED
258          * normal_instance_table + schedule_table(type=1) + calendar_table
259          * A = normal_instace_table
260          * B = schedule_table
261          * C = calendar_table
262          */
263         snprintf(query, sizeof(query),
264                         "CREATE VIEW IF NOT EXISTS %s AS SELECT A.event_id, "
265                         "B.dtstart_type, A.dtstart_utime, B.dtstart_datetime, "
266                         "B.dtend_type, A.dtend_utime, B.dtend_datetime, "
267                         "B.summary, B.description, "
268                         "B.location, B.busy_status, B.task_status, B.priority, B.sensitivity, "
269                         "B.rrule_id, B.latitude, B.longitude, B.has_alarm, B.original_event_id, "
270                         "B.calendar_id, B.last_mod, "
271                         "B.sync_data1, B.organizer_name, B.categories, B.has_attendee, B.sync_data2, B.sync_data3, B.sync_data4, "
272                         "C.visibility, C.account_id "
273                         "FROM %s as A, %s as B, %s as C "
274                         "ON A.event_id = B.id AND B.calendar_id = C.id "
275                         "where C.deleted = 0 AND B.is_deleted = 0 ",
276                         CAL_VIEW_TABLE_NORMAL_INSTANCE_EXTENDED,
277                         CAL_TABLE_NORMAL_INSTANCE,
278                         CAL_TABLE_SCHEDULE,
279                         CAL_TABLE_CALENDAR);
280         ret = cal_db_util_query_exec(query);
281         if (CALENDAR_ERROR_NONE != ret) {
282                 /* LCOV_EXCL_START */
283                 SECURE("[%s]", query);
284                 ERR("create view Fail");
285                 /* LCOV_EXCL_STOP */
286         }
287
288         /* CAL_VIEW_TABLE_ALLDAY_INSTANCE_EXTENDED  : CALENDAR_VIEW_INSTANCE_ALLDAY_CALENDAR_EXTENDED */
289         snprintf(query, sizeof(query),
290                         "CREATE VIEW IF NOT EXISTS %s AS SELECT A.event_id, "
291                         "B.dtstart_type, B.dtstart_utime, A.dtstart_datetime, "
292                         "B.dtend_type, B.dtend_utime, A.dtend_datetime, "
293                         "B.summary, B.description, "
294                         "B.location, B.busy_status, B.task_status, B.priority, B.sensitivity, "
295                         "B.rrule_id, B.latitude, B.longitude, B.has_alarm, B.original_event_id, "
296                         "B.calendar_id, B.last_mod, "
297                         "B.sync_data1, B.organizer_name, B.categories, B.has_attendee, B.sync_data2, B.sync_data3, B.sync_data4, B.is_allday, "
298                         "C.visibility, C.account_id "
299                         "FROM %s as A, %s as B, %s as C "
300                         "ON A.event_id = B.id AND B.calendar_id = C.id "
301                         "where C.deleted = 0 AND B.is_deleted = 0 ",
302                         CAL_VIEW_TABLE_ALLDAY_INSTANCE_EXTENDED,
303                         CAL_TABLE_ALLDAY_INSTANCE,
304                         CAL_TABLE_SCHEDULE,
305                         CAL_TABLE_CALENDAR);
306         ret = cal_db_util_query_exec(query);
307         if (CALENDAR_ERROR_NONE != ret) {
308                 /* LCOV_EXCL_START */
309                 SECURE("[%s]", query);
310                 ERR("create view Fail");
311                 /* LCOV_EXCL_STOP */
312         }
313
314         /*
315          * event_calendar view  :  CALENDAR_VIEW_EVENT_CALENDAR
316          * A : schedule_table
317          * B : rrule_table
318          * C : calendar_table
319          */
320         snprintf(query, sizeof(query),
321                         "CREATE VIEW IF NOT EXISTS %s AS "
322                         "SELECT "CAL_QUERY_SCHEDULE_A_ALL", "
323                         "B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
324                         "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
325                         "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst, "
326                         "C.*"
327                         "FROM %s A "
328                         "JOIN %s C ON A.calendar_id = C.id "
329                         "LEFT OUTER JOIN %s B ON A.id = B.event_id "
330                         "WHERE A.type = 1 AND c.deleted = 0 AND A.is_deleted = 0 ",
331                         CAL_VIEW_TABLE_EVENT_CALENDAR,
332                         CAL_TABLE_SCHEDULE, CAL_TABLE_CALENDAR,
333                         CAL_TABLE_RRULE);
334         ret = cal_db_util_query_exec(query);
335         if (CALENDAR_ERROR_NONE != ret) {
336                 /* LCOV_EXCL_START */
337                 SECURE("[%s]", query);
338                 ERR("create view Fail");
339                 /* LCOV_EXCL_STOP */
340         }
341
342         /*
343          * todo_calendar view  : CALENDAR_VIEW_TODO_CALENDAR
344          * A : schedule_table
345          * B : rrule_table
346          * C : calendar_table
347          */
348         snprintf(query, sizeof(query),
349                         "CREATE VIEW IF NOT EXISTS %s AS "
350                         "SELECT "CAL_QUERY_SCHEDULE_A_ALL", "
351                         "B.range_type, B.until_type, B.until_utime, B.until_datetime, B.count, "
352                         "B.interval, B.bysecond, B.byminute, B.byhour, B.byday, B.bymonthday, "
353                         "B.byyearday, B.byweekno, B.bymonth, B.bysetpos, B.wkst, "
354                         "C.*"
355                         "FROM %s A "
356                         "JOIN %s C ON A.calendar_id = C.id "
357                         "LEFT OUTER JOIN %s B ON A.id = B.event_id "
358                         "WHERE A.type = 2 AND c.deleted = 0 AND A.is_deleted = 0 ",
359                         CAL_VIEW_TABLE_TODO_CALENDAR,
360                         CAL_TABLE_SCHEDULE, CAL_TABLE_CALENDAR,
361                         CAL_TABLE_RRULE);
362         ret = cal_db_util_query_exec(query);
363         if (CALENDAR_ERROR_NONE != ret) {
364                 /* LCOV_EXCL_START */
365                 SECURE("[%s]", query);
366                 ERR("create view Fail");
367                 /* LCOV_EXCL_STOP */
368         }
369
370         /*
371          * event_calendar_attendee view  :  CALENDAR_VIEW_EVENT_CALENDAR_ATTENDEE
372          * A : schedule_table
373          * B : attendee_table
374          * C : calendar_table
375          * D : rrule_table
376          */
377         snprintf(query, sizeof(query),
378                         "CREATE VIEW IF NOT EXISTS %s AS "
379                         "SELECT "CAL_QUERY_SCHEDULE_A_ALL", "
380                         "D.range_type, D.until_type, D.until_utime, D.until_datetime, D.count, "
381                         "D.interval, D.bysecond, D.byminute, D.byhour, D.byday, D.bymonthday, "
382                         "D.byyearday, D.byweekno, D.bymonth, D.bysetpos, D.wkst, "
383                         "B.*, C.*"
384                         "FROM %s A "
385                         "LEFT OUTER  JOIN %s B ON A.id = B.event_id "
386                         "JOIN %s C ON A.calendar_id = C.id "
387                         "LEFT OUTER JOIN %s D ON A.id = D.event_id "
388                         "WHERE A.type = 1 AND c.deleted = 0 AND A.is_deleted = 0 ",
389                         CAL_VIEW_TABLE_EVENT_CALENDAR_ATTENDEE,
390                         CAL_TABLE_SCHEDULE, CAL_TABLE_ATTENDEE, CAL_TABLE_CALENDAR,
391                         CAL_TABLE_RRULE);
392         ret = cal_db_util_query_exec(query);
393         if (CALENDAR_ERROR_NONE != ret) {
394                 /* LCOV_EXCL_START */
395                 SECURE("[%s]", query);
396                 ERR("create view Fail");
397                 /* LCOV_EXCL_STOP */
398         }
399         cal_db_util_end_trans(true);
400         return ;
401 }
402
403 int cal_db_insert_record(calendar_record_h record, int* id)
404 {
405         int ret = CALENDAR_ERROR_NONE;
406
407         RETV_IF(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER);
408
409         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(((cal_record_s *)record)->type);
410         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
411         RETVM_IF(NULL == plugin_cb->insert_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
412
413         ret = cal_db_util_begin_trans();
414         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
415
416         ret = plugin_cb->insert_record(record, id);
417
418         if (CALENDAR_ERROR_NONE == ret)
419                 ret = cal_db_util_end_trans(true);
420         else
421                 cal_db_util_end_trans(false);
422
423         return ret;
424 }
425
426 int cal_db_update_record(calendar_record_h record)
427 {
428         cal_record_s *temp = NULL;
429         int ret = CALENDAR_ERROR_NONE;
430
431         RETV_IF(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER);
432
433         temp = (cal_record_s*)(record);
434
435         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(temp->type);
436         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
437         RETVM_IF(NULL == plugin_cb->update_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
438
439         ret = cal_db_util_begin_trans();
440         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
441
442         ret = plugin_cb->update_record(record);
443
444         if (CALENDAR_ERROR_NONE == ret)
445                 ret = cal_db_util_end_trans(true);
446         else
447                 cal_db_util_end_trans(false);
448
449         return ret;
450 }
451
452 int cal_db_delete_record(const char* view_uri, int id)
453 {
454         int ret = CALENDAR_ERROR_NONE;
455         cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
456
457         RETV_IF(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER);
458
459         type = cal_view_get_type(view_uri);
460
461         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(type);
462         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
463         RETVM_IF(NULL == plugin_cb->delete_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
464
465         ret = cal_db_util_begin_trans();
466         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
467
468         ret = plugin_cb->delete_record(id);
469
470         if (CALENDAR_ERROR_NONE == ret)
471                 ret = cal_db_util_end_trans(true);
472         else
473                 cal_db_util_end_trans(false);
474
475         return ret;
476 }
477
478 int cal_db_replace_record(calendar_record_h record, int record_id)
479 {
480         cal_record_s *temp = NULL;
481         int ret = CALENDAR_ERROR_NONE;
482
483         RETV_IF(NULL == record, CALENDAR_ERROR_INVALID_PARAMETER);
484         RETVM_IF(record_id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "record_id(%d)", record_id);
485
486         temp = (cal_record_s*)(record);
487
488         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(temp->type);
489         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
490         RETVM_IF(NULL == plugin_cb->replace_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
491
492         ret = cal_db_util_begin_trans();
493         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
494
495         ret = plugin_cb->replace_record(record, record_id);
496
497         if (CALENDAR_ERROR_NONE == ret)
498                 ret = cal_db_util_end_trans(true);
499         else
500                 cal_db_util_end_trans(false);
501
502         return ret;
503 }
504
505 int cal_db_get_all_records(const char* view_uri, int offset, int limit, calendar_list_h* out_list)
506 {
507         int ret = CALENDAR_ERROR_NONE;
508         cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
509         calendar_list_h list = NULL;
510
511         RETV_IF(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER);
512
513         type = cal_view_get_type(view_uri);
514
515         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(type);
516         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
517         RETVM_IF(NULL == plugin_cb->get_all_records, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
518
519         ret = plugin_cb->get_all_records(offset, limit, &list);
520         if (CALENDAR_ERROR_NONE != ret) {
521                 /* LCOV_EXCL_START */
522                 ERR("get_all_records() Fail");
523                 return ret;
524                 /* LCOV_EXCL_STOP */
525         }
526         calendar_list_first(list);
527         if (out_list) *out_list = list;
528
529         return CALENDAR_ERROR_NONE;
530 }
531
532 int cal_db_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
533 {
534         int ret = CALENDAR_ERROR_NONE;
535         cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
536         cal_query_s *que = NULL;
537         calendar_list_h list = NULL;
538
539         RETV_IF(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
540         que = (cal_query_s *)query;
541
542         type = cal_view_get_type(que->view_uri);
543
544         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(type);
545         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
546         RETVM_IF(NULL == plugin_cb->get_records_with_query, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
547
548         ret = plugin_cb->get_records_with_query(query, offset, limit, &list);
549         if (CALENDAR_ERROR_NONE != ret) {
550                 /* LCOV_EXCL_START */
551                 ERR("get_records_with_query() Fail(%d)", ret);
552                 return ret;
553                 /* LCOV_EXCL_STOP */
554         }
555         calendar_list_first(list);
556         if (out_list) *out_list = list;
557
558         return CALENDAR_ERROR_NONE;
559 }
560
561 int cal_db_get_record(const char* view_uri, int id, calendar_record_h* out_record)
562 {
563         int ret = CALENDAR_ERROR_NONE;
564         cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
565
566         RETV_IF(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER);
567
568         type = cal_view_get_type(view_uri);
569
570         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(type);
571         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
572         RETVM_IF(NULL == plugin_cb->get_record, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
573
574         ret = plugin_cb->get_record(id, out_record);
575
576         return ret;
577 }
578
579 int cal_db_clean_after_sync(int calendar_book_id, int calendar_db_version)
580 {
581         int ret = CALENDAR_ERROR_NONE;
582         char query[CAL_DB_SQL_MIN_LEN] = {0};
583         int len = 0;
584
585         RETVM_IF(calendar_book_id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "calendar_id(%d) is Invalid", calendar_book_id);
586
587         ret = cal_db_util_begin_trans();
588         if (CALENDAR_ERROR_NONE != ret) {
589                 /* LCOV_EXCL_START */
590                 ERR("cal_db_util_begin_trans() Fail");
591                 return CALENDAR_ERROR_DB_FAILED;
592                 /* LCOV_EXCL_STOP */
593         }
594         /* !! please check rrule_table, alarm_table, attendee_table ..*/
595
596         ret =  cal_is_owner(calendar_book_id);
597         if (CALENDAR_ERROR_NONE != ret) {
598                 /* LCOV_EXCL_START */
599                 if (CALENDAR_ERROR_PERMISSION_DENIED == ret)
600                         ERR("Does not have permission of calendar_book (%d)", calendar_book_id);
601                 else
602                         ERR("cal_is_owner() Fail(%d)", ret);
603                 cal_db_util_end_trans(false);
604                 return ret;
605                 /* LCOV_EXCL_STOP */
606         }
607
608         /* delete event table */
609         len = snprintf(query, sizeof(query), "DELETE FROM %s WHERE is_deleted = 1 AND calendar_id = %d",
610                         CAL_TABLE_SCHEDULE, calendar_book_id);
611         if (0 < calendar_db_version)
612                 len = snprintf(query+len, sizeof(query)-len, " AND changed_ver <= %d", calendar_db_version);
613
614         ret = cal_db_util_query_exec(query);
615         if (CALENDAR_ERROR_NONE != ret) {
616                 /* LCOV_EXCL_START */
617                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
618                 SECURE("[%s]", query);
619                 cal_db_util_end_trans(false);
620                 return ret;
621                 /* LCOV_EXCL_STOP */
622         }
623
624         /* delete delete table */
625         snprintf(query, sizeof(query), "DELETE FROM %s WHERE calendar_id = %d",
626                         CAL_TABLE_DELETED, calendar_book_id);
627         ret = cal_db_util_query_exec(query);
628         if (CALENDAR_ERROR_NONE != ret) {
629                 /* LCOV_EXCL_START */
630                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
631                 SECURE("[%s]", query);
632                 cal_db_util_end_trans(false);
633                 return ret;
634                 /* LCOV_EXCL_STOP */
635         }
636
637         cal_db_util_end_trans(true);
638         return CALENDAR_ERROR_NONE;
639 }
640
641 int cal_db_get_count(const char* view_uri, int *out_count)
642 {
643         int ret = CALENDAR_ERROR_NONE;
644         cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
645
646         RETV_IF(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER);
647
648         type = cal_view_get_type(view_uri);
649
650         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(type);
651         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
652         RETVM_IF(NULL == plugin_cb->get_count, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
653
654         ret = plugin_cb->get_count(out_count);
655         return ret;
656 }
657
658 int cal_db_get_count_with_query(calendar_query_h query, int *out_count)
659 {
660         int ret = CALENDAR_ERROR_NONE;
661         cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
662         cal_query_s *que = NULL;
663
664         RETV_IF(NULL == query, CALENDAR_ERROR_INVALID_PARAMETER);
665         que = (cal_query_s *)query;
666
667         type = cal_view_get_type(que->view_uri);
668
669         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(type);
670         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
671         RETVM_IF(NULL == plugin_cb->get_count_with_query, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
672
673         ret = plugin_cb->get_count_with_query(query, out_count);
674         return ret;
675 }
676
677 int cal_db_insert_records(calendar_list_h list, int** ids, int* count)
678 {
679         int ret = CALENDAR_ERROR_NONE;
680         int i;
681         int *_ids = NULL;
682         int _count = 0;
683
684         RETVM_IF(NULL == list, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
685
686         ret = cal_db_util_begin_trans();
687         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
688
689         _count = 0;
690         calendar_list_get_count(list, &_count);
691         DBG("list count(%d)", _count);
692
693         _ids = calloc(_count, sizeof(int));
694
695         /* divide count for accessing of another modules */
696         int div = (int)(_count / BULK_DEFAULT_COUNT) + 1;
697         int bulk = _count / div + 1;
698
699         calendar_list_first(list);
700         for (i = 0; i < _count; i++) {
701                 calendar_record_h record = NULL;
702                 ret = calendar_list_get_current_record_p(list, &record);
703                 if (NULL == record || CALENDAR_ERROR_NONE != ret) {
704                         /* LCOV_EXCL_START */
705                         ERR("No record in the list");
706                         cal_db_util_end_trans(false);
707                         CAL_FREE(_ids);
708                         return ret;
709                         /* LCOV_EXCL_STOP */
710                 }
711
712                 cal_record_s *temp = (cal_record_s *)record;
713                 cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(temp->type);
714                 if (NULL == plugin_cb || NULL == plugin_cb->insert_record) {
715                         /* LCOV_EXCL_START */
716                         ERR("Not plugin");
717                         cal_db_util_end_trans(false);
718                         CAL_FREE(_ids);
719                         return CALENDAR_ERROR_NOT_PERMITTED;
720                         /* LCOV_EXCL_STOP */
721                 }
722                 ret = plugin_cb->insert_record(record, &_ids[i]);
723                 if (CALENDAR_ERROR_NONE != ret) {
724                         /* LCOV_EXCL_START */
725                         ERR("insert_record() Fail(%d)", ret);
726                         cal_db_util_end_trans(false);
727                         CAL_FREE(_ids);
728                         return ret;
729                         /* LCOV_EXCL_STOP */
730                 }
731                 DBG("insert with id(%d)", _ids[i]);
732                 calendar_list_next(list);
733
734                 if (bulk < i) {
735                         bulk += (_count / div + 1);
736                         cal_db_util_end_trans(true);
737                         sleep(1);
738                         ret = cal_db_util_begin_trans();
739                         if (CALENDAR_ERROR_NONE != ret) {
740                                 /* LCOV_EXCL_START */
741                                 ERR("cal_db_util_begin_trans() Fail(%d)", ret);
742                                 calendar_list_destroy(list, true);
743                                 CAL_FREE(_ids);
744                                 return CALENDAR_ERROR_DB_FAILED;
745                                 /* LCOV_EXCL_STOP */
746                         }
747                 }
748         }
749
750         if (ids)
751                 *ids = _ids;
752         else
753                 CAL_FREE(_ids);
754
755         if (count)
756                 *count = _count;
757         cal_db_util_end_trans(true);
758
759         return ret;
760 }
761
762 int cal_db_update_records(calendar_list_h list)
763 {
764         int i;
765         int count = 0;
766         int ret = CALENDAR_ERROR_NONE;
767
768         RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
769
770         calendar_list_get_count(list, &count);
771         DBG("update list count(%d", count);
772         if (0 == count) {
773                 DBG("Nothing to update");
774                 return CALENDAR_ERROR_NONE;
775         }
776         ret = cal_db_util_begin_trans();
777         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
778
779         /* divide count for accessing of another modules */
780         int div = (int)(count / BULK_DEFAULT_COUNT) + 1;
781         int bulk = count / div + 1;
782
783         calendar_list_first(list);
784         for (i = 0; i < count; i++) {
785                 calendar_record_h record = NULL;
786                 ret = calendar_list_get_current_record_p(list, &record);
787                 if (NULL == record || CALENDAR_ERROR_NONE != ret) {
788                         /* LCOV_EXCL_START */
789                         ERR("No record in the list");
790                         cal_db_util_end_trans(false);
791                         return ret;
792                         /* LCOV_EXCL_STOP */
793                 }
794
795                 cal_record_s *temp = (cal_record_s *)record;
796                 cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(temp->type);
797                 if (NULL == plugin_cb || NULL == plugin_cb->update_record) {
798                         /* LCOV_EXCL_START */
799                         ERR("Not plugin");
800                         cal_db_util_end_trans(false);
801                         ret = CALENDAR_ERROR_NOT_PERMITTED;
802                         return ret;
803                         /* LCOV_EXCL_STOP */
804                 }
805                 ret = plugin_cb->update_record(record);
806                 if (CALENDAR_ERROR_NONE != ret) {
807                         /* LCOV_EXCL_START */
808                         ERR("update_record() Fail(%d)", ret);
809                         cal_db_util_end_trans(false);
810                         return ret;
811                         /* LCOV_EXCL_STOP */
812                 }
813                 DBG("update record");
814                 calendar_list_next(list);
815
816                 if (bulk < i) {
817                         bulk += (count / div + 1);
818                         cal_db_util_end_trans(true);
819                         sleep(1);
820
821                         ret = cal_db_util_begin_trans();
822                         if (CALENDAR_ERROR_NONE != ret) {
823                                 /* LCOV_EXCL_START */
824                                 ERR("cal_db_util_begin_trans() Fail(%d)", ret);
825                                 calendar_list_destroy(list, true);
826                                 return CALENDAR_ERROR_DB_FAILED;
827                                 /* LCOV_EXCL_STOP */
828                         }
829                 }
830         }
831         cal_db_util_end_trans(true);
832
833         return ret;
834 }
835
836 int cal_db_delete_records(const char* view_uri, int record_id_array[], int count)
837 {
838         RETV_IF(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER);
839         RETV_IF(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER);
840         RETVM_IF(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "count(%d)", count);
841
842         int ret = CALENDAR_ERROR_NONE;
843         cal_record_type_e type = CAL_RECORD_TYPE_INVALID;
844
845         type = cal_view_get_type(view_uri);
846
847         cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(type);
848         RETV_IF(NULL == plugin_cb, CALENDAR_ERROR_INVALID_PARAMETER);
849         RETVM_IF(NULL == plugin_cb->delete_records, CALENDAR_ERROR_NOT_PERMITTED, "Not permitted");
850
851         ret = cal_db_util_begin_trans();
852         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
853
854         ret = plugin_cb->delete_records(record_id_array, count);
855
856         if (CALENDAR_ERROR_NONE == ret)
857                 ret = cal_db_util_end_trans(true);
858         else
859                 cal_db_util_end_trans(false);
860
861         return ret;
862 }
863
864 int cal_db_replace_records(calendar_list_h list, int *ids, int count)
865 {
866         int i;
867         int ret = CALENDAR_ERROR_NONE;
868
869         RETV_IF(NULL == list, CALENDAR_ERROR_INVALID_PARAMETER);
870         RETV_IF(NULL == ids, CALENDAR_ERROR_INVALID_PARAMETER);
871         RETVM_IF(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "count(%d)", count);
872
873         ret = cal_db_util_begin_trans();
874         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_DB_FAILED, "cal_db_util_begin_trans() Fail(%d)", ret);
875
876         calendar_list_first(list);
877         for (i = 0; i < count; i++) {
878                 calendar_record_h record = NULL;
879                 ret = calendar_list_get_current_record_p(list, &record);
880                 if (NULL == record || CALENDAR_ERROR_NONE != ret) {
881                         /* LCOV_EXCL_START */
882                         ERR("No record in the list");
883                         cal_db_util_end_trans(false);
884                         return ret;
885                         /* LCOV_EXCL_STOP */
886                 }
887
888                 cal_record_s *temp = (cal_record_s *)record;
889                 cal_db_plugin_cb_s* plugin_cb = _cal_db_get_plugin(temp->type);
890                 if (NULL == plugin_cb || NULL == plugin_cb->insert_record) {
891                         /* LCOV_EXCL_START */
892                         ERR("Not plugin");
893                         cal_db_util_end_trans(false);
894                         ret = CALENDAR_ERROR_NOT_PERMITTED;
895                         return ret;
896                         /* LCOV_EXCL_STOP */
897                 }
898                 ret = plugin_cb->replace_record(record, ids[i]);
899                 if (CALENDAR_ERROR_NONE != ret) {
900                         /* LCOV_EXCL_START */
901                         ERR("replace_record() Fail(%d)", ret);
902                         cal_db_util_end_trans(false);
903                         return ret;
904                         /* LCOV_EXCL_STOP */
905                 }
906                 DBG("insert with id(%d)", ids[i]);
907                 calendar_list_next(list);
908         }
909         cal_db_util_end_trans(true);
910         return ret;
911 }
912
913 int cal_db_insert_vcalendars(const char* vcalendar_stream, int **record_id_array, int *count)
914 {
915         int ret = CALENDAR_ERROR_NONE;
916         calendar_list_h list = NULL;
917         int list_count = 0;
918         int i = 0;
919         int *ids = NULL;
920
921         RETV_IF(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER);
922         RETV_IF(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER);
923         RETV_IF(NULL == count, CALENDAR_ERROR_INVALID_PARAMETER);
924
925         ret = calendar_vcalendar_parse_to_calendar(vcalendar_stream, &list);
926         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_vcalendar_parse_to_calendar() Fail(%d)", ret);
927
928         ret = calendar_list_get_count(list, &list_count);
929         if (CALENDAR_ERROR_NONE != ret) {
930                 /* LCOV_EXCL_START */
931                 ERR("calendar_list_get_count() Fail(%d)", ret);
932                 calendar_list_destroy(list, true);
933                 return ret;
934                 /* LCOV_EXCL_STOP */
935         }
936
937         calendar_list_first(list);
938         ids = calloc(1, sizeof(int)*list_count);
939         if (NULL == ids) {
940                 /* LCOV_EXCL_START */
941                 ERR("calloc() Fail");
942                 calendar_list_destroy(list, true);
943                 return CALENDAR_ERROR_OUT_OF_MEMORY;
944                 /* LCOV_EXCL_STOP */
945         }
946
947         ret = cal_db_util_begin_trans();
948
949         if (CALENDAR_ERROR_NONE != ret) {
950                 /* LCOV_EXCL_START */
951                 ERR("cal_db_util_begin_trans() Fail(%d)", ret);
952                 calendar_list_destroy(list, true);
953                 CAL_FREE(ids);
954                 return CALENDAR_ERROR_DB_FAILED;
955                 /* LCOV_EXCL_STOP */
956         }
957
958         for (i = 0; i < list_count; i++) {
959                 calendar_record_h record = NULL;
960
961                 ret = calendar_list_get_current_record_p(list, &record);
962                 if (CALENDAR_ERROR_NONE != ret) {
963                         /* LCOV_EXCL_START */
964                         ERR("calendar_list_get_current_record_p() Fail(%d)", ret);
965                         calendar_list_destroy(list, true);
966                         CAL_FREE(ids);
967                         cal_db_util_end_trans(false);
968                         return ret;
969                         /* LCOV_EXCL_STOP */
970                 }
971
972                 ret = cal_db_insert_record(record, &ids[i]);
973                 if (CALENDAR_ERROR_NONE != ret) {
974                         /* LCOV_EXCL_START */
975                         ERR("cal_db_insert_record() Fail(%d)", ret);
976                         calendar_list_destroy(list, true);
977                         CAL_FREE(ids);
978                         cal_db_util_end_trans(false);
979                         return ret;
980                         /* LCOV_EXCL_STOP */
981                 }
982
983                 calendar_list_next(list);
984         }
985
986         cal_db_util_end_trans(true);
987
988         *record_id_array = ids;
989         *count = list_count;
990
991         calendar_list_destroy(list, true);
992         return ret;
993 }
994
995 int cal_db_replace_vcalendars(const char* vcalendar_stream, int *record_id_array, int count)
996 {
997         int ret = CALENDAR_ERROR_NONE;
998         calendar_list_h list = NULL;
999         int list_count = 0;
1000         int i = 0;
1001
1002         RETV_IF(NULL == vcalendar_stream, CALENDAR_ERROR_INVALID_PARAMETER);
1003         RETV_IF(NULL == record_id_array, CALENDAR_ERROR_INVALID_PARAMETER);
1004         RETVM_IF(count <= 0, CALENDAR_ERROR_INVALID_PARAMETER, "count(%d)", count);
1005
1006         ret = calendar_vcalendar_parse_to_calendar(vcalendar_stream, &list);
1007         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_vcalendar_parse_to_calendar() Fail(%d)", ret);
1008
1009         ret = calendar_list_get_count(list, &list_count);
1010         if (CALENDAR_ERROR_NONE != ret) {
1011                 /* LCOV_EXCL_START */
1012                 ERR("calendar_list_get_count() Fail(%d)", ret);
1013                 calendar_list_destroy(list, true);
1014                 return ret;
1015                 /* LCOV_EXCL_STOP */
1016         }
1017
1018         if (count != list_count) {
1019                 calendar_list_destroy(list, true);
1020                 /* LCOV_EXCL_START */
1021                 ERR("Mismatched count: vcalendar_count=%d, input count=%d", list_count, count);
1022                 return CALENDAR_ERROR_INVALID_PARAMETER;
1023                 /* LCOV_EXCL_STOP */
1024         }
1025
1026         calendar_list_first(list);
1027
1028         ret = cal_db_util_begin_trans();
1029         if (CALENDAR_ERROR_NONE != ret) {
1030                 calendar_list_destroy(list, true);
1031                 /* LCOV_EXCL_START */
1032                 ERR("cal_db_util_begin_trans() Fail(%d)", ret);
1033                 return CALENDAR_ERROR_DB_FAILED;
1034                 /* LCOV_EXCL_STOP */
1035         }
1036
1037         /* divide count for accessing of another modules */
1038         int div = (int)(count / BULK_DEFAULT_COUNT) + 1;
1039         int bulk = count / div + 1;
1040
1041         for (i = 0; i < list_count; i++) {
1042                 calendar_record_h record = NULL;
1043                 char *view_uri = NULL;
1044
1045                 ret = calendar_list_get_current_record_p(list, &record);
1046                 if (CALENDAR_ERROR_NONE != ret) {
1047                         /* LCOV_EXCL_START */
1048                         ERR("calendar_list_get_current_record_p() Fail(%d)", ret);
1049                         calendar_list_destroy(list, true);
1050                         cal_db_util_end_trans(false);
1051                         return ret;
1052                         /* LCOV_EXCL_STOP */
1053                 }
1054
1055                 /* set_id */
1056                 ret = calendar_record_get_uri_p(record, &view_uri);
1057                 if (CALENDAR_ERROR_NONE != ret) {
1058                         /* LCOV_EXCL_START */
1059                         ERR("calendar_record_get_uri_p() Fail(%d)", ret);
1060                         calendar_list_destroy(list, true);
1061                         cal_db_util_end_trans(false);
1062                         return ret;
1063                         /* LCOV_EXCL_STOP */
1064                 }
1065
1066                 if (CAL_STRING_EQUAL == strcmp(view_uri, _calendar_event._uri)) {
1067                         ret = cal_record_set_int(record, _calendar_event.id, record_id_array[i]);
1068                 } else if (CAL_STRING_EQUAL == strcmp(view_uri, _calendar_todo._uri)) {
1069                         ret = cal_record_set_int(record, _calendar_todo.id, record_id_array[i]);
1070                 } else {
1071                         DBG("this uri[%s] is not replacable.", view_uri);
1072                         calendar_list_next(list);
1073                         continue;
1074                 }
1075
1076                 if (CALENDAR_ERROR_NONE != ret) {
1077                         /* LCOV_EXCL_START */
1078                         ERR("cal_record_set_int() Fail(%d)", ret);
1079                         calendar_list_destroy(list, true);
1080                         cal_db_util_end_trans(false);
1081                         /* LCOV_EXCL_STOP */
1082                         return ret;
1083                 }
1084
1085                 /* update */
1086                 ret = cal_db_update_record(record);
1087                 if (CALENDAR_ERROR_NONE != ret) {
1088                         /* LCOV_EXCL_START */
1089                         ERR("cal_db_update_record() Fail(%d)", ret);
1090                         calendar_list_destroy(list, true);
1091                         cal_db_util_end_trans(false);
1092                         return ret;
1093                         /* LCOV_EXCL_STOP */
1094                 }
1095                 calendar_list_next(list);
1096
1097                 if (bulk < i) {
1098                         bulk += (count / div + 1);
1099                         cal_db_util_end_trans(true);
1100                         sleep(1);
1101                         ret = cal_db_util_begin_trans();
1102                         if (CALENDAR_ERROR_NONE != ret) {
1103                                 calendar_list_destroy(list, true);
1104                                 /* LCOV_EXCL_START */
1105                                 ERR("cal_db_util_begin_trans() Fail(%d)", ret);
1106                                 return CALENDAR_ERROR_DB_FAILED;
1107                                 /* LCOV_EXCL_STOP */
1108                         }
1109                 }
1110         }
1111
1112         cal_db_util_end_trans(true);
1113
1114         calendar_list_destroy(list, true);
1115
1116         return ret;
1117 }
1118
1119 int cal_db_get_current_version(int* current_version)
1120 {
1121         const char *query = "SELECT ver FROM "CAL_TABLE_VERSION;
1122         int transaction_ver = 0;
1123         int ret;
1124
1125         RETV_IF(NULL == current_version, CALENDAR_ERROR_INVALID_PARAMETER);
1126
1127         ret = cal_db_util_query_get_first_int_result(query, NULL, &transaction_ver);
1128         if (CALENDAR_ERROR_NONE != ret) {
1129                 /* LCOV_EXCL_START */
1130                 ERR("cal_db_util_query_get_first_int_result() Fail(%d)", ret);
1131                 return ret;
1132                 /* LCOV_EXCL_STOP */
1133         }
1134         if (current_version) *current_version = transaction_ver;
1135
1136         return CALENDAR_ERROR_NONE;
1137 }
1138
1139 int cal_db_get_changes_by_version(const char* view_uri, int calendar_book_id, int calendar_db_version, calendar_list_h* record_list, int *current_calendar_db_version)
1140 {
1141         const char *query_cur_version = "SELECT ver FROM "CAL_TABLE_VERSION;
1142         int transaction_ver = 0;
1143         char query[CAL_DB_SQL_MAX_LEN] = {0};
1144         sqlite3_stmt *stmt = NULL;
1145         int ret = 0;
1146         int is_deleted = 0;
1147
1148         RETV_IF(NULL == current_calendar_db_version, CALENDAR_ERROR_INVALID_PARAMETER);
1149         RETV_IF(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER);
1150         RETV_IF(NULL == record_list, CALENDAR_ERROR_INVALID_PARAMETER);
1151
1152         ret = cal_db_util_query_get_first_int_result(query_cur_version, NULL, &transaction_ver);
1153         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_query_get_first_int_result() Fail(%d)", ret);
1154
1155         char buf[CAL_STR_SHORT_LEN64] = {0};
1156         if (0 < calendar_book_id)
1157                 snprintf(buf, sizeof(buf), "AND calendar_id = %d ", calendar_book_id);
1158         else
1159                 memset(buf, 0x0, sizeof(buf));
1160
1161         int schedule_type = 0;
1162         int record_type = 0;
1163         if (CAL_STRING_EQUAL == strcmp(view_uri, _calendar_event._uri)) {
1164                 schedule_type = CAL_SCH_TYPE_EVENT;
1165                 record_type = CAL_RECORD_TYPE_EVENT;
1166
1167         } else if (CAL_STRING_EQUAL == strcmp(view_uri, _calendar_todo._uri)) {
1168                 schedule_type = CAL_SCH_TYPE_TODO;
1169                 record_type = CAL_RECORD_TYPE_TODO;
1170         } else {
1171                 /* LCOV_EXCL_START */
1172                 ERR("Invalid parameter");
1173                 return CALENDAR_ERROR_INVALID_PARAMETER;
1174                 /* LCOV_EXCL_STOP */
1175         }
1176
1177         snprintf(query, sizeof(query),
1178                         "SELECT id, changed_ver, created_ver, is_deleted, calendar_id FROM %s "
1179                         "WHERE changed_ver > %d AND changed_ver <= %d AND type = %d AND original_event_id < 0 %s "
1180                         "UNION "
1181                         "SELECT schedule_id, deleted_ver, created_ver, 1, calendar_id FROM %s "
1182                         "WHERE deleted_ver > %d AND schedule_type = %d AND original_event_id < 0 %s ",
1183                         CAL_TABLE_SCHEDULE,
1184                         calendar_db_version, transaction_ver, schedule_type, buf,
1185                         CAL_TABLE_DELETED,
1186                         calendar_db_version, record_type, buf);
1187         SEC_DBG("query[%s]", query);
1188
1189         ret = calendar_list_create(record_list);
1190         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
1191
1192         ret = cal_db_util_query_prepare(query, &stmt);
1193         if (CALENDAR_ERROR_NONE != ret) {
1194                 /* LCOV_EXCL_START */
1195                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1196                 calendar_list_destroy(*record_list, true);
1197                 *record_list = NULL;
1198                 return CALENDAR_ERROR_DB_FAILED;
1199                 /* LCOV_EXCL_STOP */
1200         }
1201
1202         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
1203                 calendar_record_h record;
1204                 int id = 0, calendar_id = 0, type = 0;
1205                 int ver = 0;
1206                 int created_ver = 0;
1207
1208                 ret = calendar_record_create(_calendar_updated_info._uri, &record);
1209                 if (CALENDAR_ERROR_NONE != ret) {
1210                         /* LCOV_EXCL_START */
1211                         ERR("calendar_record_create() Fail");
1212                         calendar_list_destroy(*record_list, true);
1213                         *record_list = NULL;
1214                         sqlite3_finalize(stmt);
1215                         return ret;
1216                         /* LCOV_EXCL_STOP */
1217                 }
1218
1219                 id = sqlite3_column_int(stmt, 0);
1220                 ver = sqlite3_column_int(stmt, 1);
1221                 created_ver = sqlite3_column_int(stmt, 2);
1222                 is_deleted = sqlite3_column_int(stmt, 3);
1223                 if (is_deleted == 1)
1224                         type = CALENDAR_RECORD_MODIFIED_STATUS_DELETED;
1225                 else if (created_ver != ver)
1226                         type = CALENDAR_RECORD_MODIFIED_STATUS_UPDATED;
1227                 else
1228                         type = CALENDAR_RECORD_MODIFIED_STATUS_INSERTED;
1229
1230                 calendar_id = sqlite3_column_int(stmt, 4);
1231
1232                 if (type == CALENDAR_RECORD_MODIFIED_STATUS_DELETED && calendar_db_version < created_ver) {
1233                         calendar_record_destroy(record, true);
1234                         DBG("type is deleted, created_ver(%d) > calendar_db_ver(%d), so skip", created_ver, calendar_db_version);
1235                         continue;
1236                 }
1237
1238                 cal_record_set_int(record, _calendar_updated_info.id, id);
1239                 cal_record_set_int(record, _calendar_updated_info.calendar_book_id, calendar_id);
1240                 cal_record_set_int(record, _calendar_updated_info.modified_status, type);
1241                 cal_record_set_int(record, _calendar_updated_info.version, ver);
1242
1243                 ret = calendar_list_add(*record_list, record);
1244                 if (CALENDAR_ERROR_NONE != ret) {
1245                         /* LCOV_EXCL_START */
1246                         ERR("calendar_list_add() Fail");
1247                         calendar_list_destroy(*record_list, true);
1248                         *record_list = NULL;
1249                         calendar_record_destroy(record, true);
1250                         sqlite3_finalize(stmt);
1251                         return ret;
1252                         /* LCOV_EXCL_STOP */
1253                 }
1254         }
1255
1256         *current_calendar_db_version = transaction_ver;
1257         sqlite3_finalize(stmt);
1258
1259         calendar_list_first(*record_list);
1260
1261         return CALENDAR_ERROR_NONE;
1262 }
1263
1264 int cal_db_get_changes_exception_by_version(const char* view_uri, int original_event_id, int calendar_db_version, calendar_list_h* record_list)
1265 {
1266         const char *query_cur_version = "SELECT ver FROM "CAL_TABLE_VERSION;
1267         int transaction_ver = 0;
1268         char query[CAL_DB_SQL_MAX_LEN] = {0};
1269         sqlite3_stmt *stmt = NULL;
1270         int ret = 0;
1271         int is_deleted = 0;
1272
1273         RETV_IF(NULL == view_uri, CALENDAR_ERROR_INVALID_PARAMETER);
1274         RETV_IF(NULL == record_list, CALENDAR_ERROR_INVALID_PARAMETER);
1275         RETV_IF(original_event_id <= 0, CALENDAR_ERROR_INVALID_PARAMETER);
1276
1277         ret = cal_db_util_query_get_first_int_result(query_cur_version, NULL, &transaction_ver);
1278         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "cal_db_util_query_get_first_int_result() Fail");
1279
1280         int schedule_type = 0;
1281         int record_type = 0;
1282         if (CAL_STRING_EQUAL == strcmp(view_uri, _calendar_event._uri)) {
1283                 schedule_type = CAL_SCH_TYPE_EVENT;
1284                 record_type = CAL_RECORD_TYPE_EVENT;
1285
1286         } else {
1287                 /* LCOV_EXCL_START */
1288                 ERR("Invalid parameter");
1289                 return CALENDAR_ERROR_INVALID_PARAMETER;
1290                 /* LCOV_EXCL_STOP */
1291         }
1292
1293         snprintf(query, sizeof(query),
1294                         "SELECT id, changed_ver, created_ver, is_deleted, calendar_id FROM %s "
1295                         "WHERE changed_ver > %d AND changed_ver <= %d AND type = %d AND original_event_id = %d "
1296                         "UNION "
1297                         "SELECT schedule_id, deleted_ver, created_ver, 1, calendar_id FROM %s "
1298                         "WHERE deleted_ver > %d AND schedule_type = %d AND original_event_id = %d ",
1299                         CAL_TABLE_SCHEDULE,
1300                         calendar_db_version, transaction_ver, schedule_type, original_event_id,
1301                         CAL_TABLE_DELETED,
1302                         calendar_db_version, record_type, original_event_id);
1303         SEC_DBG("query[%s]", query);
1304
1305         ret = calendar_list_create(record_list);
1306         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
1307
1308         ret = cal_db_util_query_prepare(query, &stmt);
1309         if (CALENDAR_ERROR_NONE != ret) {
1310                 /* LCOV_EXCL_START */
1311                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1312                 calendar_list_destroy(*record_list, true);
1313                 *record_list = NULL;
1314                 return CALENDAR_ERROR_DB_FAILED;
1315                 /* LCOV_EXCL_STOP */
1316         }
1317
1318         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
1319                 calendar_record_h record;
1320                 int id = 0, calendar_id = 0, type = 0;
1321                 int ver = 0;
1322                 int created_ver = 0;
1323
1324                 ret = calendar_record_create(_calendar_updated_info._uri, &record);
1325                 if (CALENDAR_ERROR_NONE != ret) {
1326                         /* LCOV_EXCL_START */
1327                         ERR("calendar_record_create() Fail");
1328                         calendar_list_destroy(*record_list, true);
1329                         *record_list = NULL;
1330                         sqlite3_finalize(stmt);
1331                         return ret;
1332                         /* LCOV_EXCL_STOP */
1333                 }
1334
1335                 id = sqlite3_column_int(stmt, 0);
1336                 ver = sqlite3_column_int(stmt, 1);
1337                 created_ver = sqlite3_column_int(stmt, 2);
1338                 is_deleted = sqlite3_column_int(stmt, 3);
1339                 if (is_deleted == 1)
1340                         type = CALENDAR_RECORD_MODIFIED_STATUS_DELETED;
1341                 else if (created_ver != ver)
1342                         type = CALENDAR_RECORD_MODIFIED_STATUS_UPDATED;
1343                 else
1344                         type = CALENDAR_RECORD_MODIFIED_STATUS_INSERTED;
1345
1346
1347                 calendar_id = sqlite3_column_int(stmt, 4);
1348
1349                 cal_record_set_int(record, _calendar_updated_info.id, id);
1350                 cal_record_set_int(record, _calendar_updated_info.calendar_book_id, calendar_id);
1351                 cal_record_set_int(record, _calendar_updated_info.modified_status, type);
1352                 cal_record_set_int(record, _calendar_updated_info.version, ver);
1353
1354                 ret = calendar_list_add(*record_list, record);
1355                 if (CALENDAR_ERROR_NONE != ret) {
1356                         /* LCOV_EXCL_START */
1357                         ERR("calendar_list_add() Fail");
1358                         calendar_list_destroy(*record_list, true);
1359                         *record_list = NULL;
1360                         calendar_record_destroy(record, true);
1361                         sqlite3_finalize(stmt);
1362                         return ret;
1363                         /* LCOV_EXCL_STOP */
1364                 }
1365         }
1366
1367         sqlite3_finalize(stmt);
1368         calendar_list_first(*record_list);
1369
1370         return CALENDAR_ERROR_NONE;
1371 }