remove unused function: replace records in plugin
[platform/core/pim/calendar-service.git] / server / db / cal_db_plugin_todo.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 <stdio.h>
21 #include <stdlib.h>
22
23 #include "cal_internal.h"
24 #include "cal_typedef.h"
25 #include "cal_view.h"
26 #include "cal_record.h"
27 #include "cal_list.h"
28
29 #include "cal_db_util.h"
30 #include "cal_db.h"
31 #include "cal_db_query.h"
32 #include "cal_db_rrule.h"
33 #include "cal_db_plugin_alarm_helper.h"
34 #include "cal_db_plugin_attendee_helper.h"
35 #include "cal_db_plugin_extended_helper.h"
36 #include "cal_access_control.h"
37 #include "cal_utils.h"
38
39 static int _cal_db_todo_insert_record(calendar_record_h record, int* id);
40 static int _cal_db_todo_get_record(int id, calendar_record_h* out_record);
41 static int _cal_db_todo_update_record(calendar_record_h record);
42 static int _cal_db_todo_delete_record(int id);
43 static int _cal_db_todo_get_all_records(int offset, int limit, calendar_list_h* out_list);
44 static int _cal_db_todo_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list);
45 static int _cal_db_todo_delete_records(int ids[], int count);
46 static int _cal_db_todo_get_count(int *out_count);
47 static int _cal_db_todo_get_count_with_query(calendar_query_h query, int *out_count);
48 static int _cal_db_todo_replace_record(calendar_record_h record, int id);
49
50 /*
51  * static function
52  */
53 static void _cal_db_todo_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record, int *extended);
54 static void _cal_db_todo_get_property_stmt(sqlite3_stmt *stmt,
55                 unsigned int property, int *stmt_count, calendar_record_h record);
56 static void _cal_db_todo_get_projection_stmt(sqlite3_stmt *stmt,
57                 const unsigned int *projection, const int projection_count,
58                 calendar_record_h record);
59 static int _cal_db_todo_update_dirty(calendar_record_h record);
60 static int _cal_db_todo_get_deleted_data(int id, int* calendar_book_id, int* created_ver);
61 static bool _cal_db_todo_check_calendar_book_type(calendar_record_h record);
62
63 cal_db_plugin_cb_s cal_db_todo_plugin_cb = {
64         .is_query_only = false,
65         .insert_record = _cal_db_todo_insert_record,
66         .get_record = _cal_db_todo_get_record,
67         .update_record = _cal_db_todo_update_record,
68         .delete_record = _cal_db_todo_delete_record,
69         .get_all_records = _cal_db_todo_get_all_records,
70         .get_records_with_query = _cal_db_todo_get_records_with_query,
71         .insert_records = NULL,
72         .update_records = NULL,
73         .delete_records = _cal_db_todo_delete_records,
74         .get_count = _cal_db_todo_get_count,
75         .get_count_with_query = _cal_db_todo_get_count_with_query,
76         .replace_record = _cal_db_todo_replace_record,
77         .replace_records = NULL
78 };
79
80 static int _cal_db_todo_insert_record(calendar_record_h record, int* id)
81 {
82         int ret = -1;
83         int index = -1;
84         int input_ver;
85         char query[CAL_DB_SQL_MAX_LEN] = {0};
86         char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
87         char dtend_datetime[CAL_STR_SHORT_LEN32] = {0};
88         sqlite3_stmt *stmt = NULL;
89         cal_todo_s* todo =  (cal_todo_s*)(record);
90         cal_rrule_s *rrule = NULL;
91         int tmp = 0;
92         int calendar_book_id = 0;
93         calendar_record_h record_calendar = NULL;
94         int has_alarm = 0;
95
96         RETV_IF(NULL == todo, CALENDAR_ERROR_INVALID_PARAMETER);
97         RETV_IF(false == _cal_db_todo_check_calendar_book_type(record), CALENDAR_ERROR_INVALID_PARAMETER);
98
99         if (cal_access_control_have_write_permission(todo->calendar_id) == false) {
100                 /* LCOV_EXCL_START */
101                 ERR("cal_access_control_have_write_permission() Fail");
102                 return CALENDAR_ERROR_PERMISSION_DENIED;
103                 /* LCOV_EXCL_STOP */
104         }
105
106         ret = calendar_record_get_int(record,
107                         _calendar_todo.calendar_book_id, &calendar_book_id);
108         DBG("calendar_book_id(%d)", calendar_book_id);
109
110         ret = cal_db_get_record(_calendar_book._uri,
111                         calendar_book_id, &record_calendar);
112         RETVM_IF(CALENDAR_ERROR_NONE != ret, CALENDAR_ERROR_INVALID_PARAMETER, "calendar_book_id is invalid");
113
114         calendar_record_destroy(record_calendar, true);
115
116         has_alarm = cal_db_alarm_has_alarm(todo->alarm_list);
117         input_ver = cal_db_util_get_next_ver();
118         int is_allday = 0;
119         if (CALENDAR_TIME_LOCALTIME == todo->start.type
120                         && (0 == todo->start.time.date.hour)
121                         && (0 == todo->start.time.date.minute)
122                         && (0 == todo->start.time.date.second)
123                         && (0 == todo->due.time.date.hour)
124                         && (0 == todo->due.time.date.minute)
125                         && (0 == todo->due.time.date.second)) {
126                 is_allday = 1;
127         }
128
129         ret = snprintf(query, sizeof(query),
130                         "INSERT INTO %s ("
131                         "type, "
132                         "created_ver, changed_ver, "
133                         "summary, description, location, categories,  "
134                         "task_status, priority, "
135                         "sensitivity, uid, "
136                         "calendar_id, "
137                         "latitude, longitude, "
138                         "created_time, completed_time, progress, "
139                         "dtstart_type, dtstart_utime, dtstart_datetime, dtstart_tzid, "
140                         "dtend_type, dtend_utime, dtend_datetime, dtend_tzid, "
141                         "last_mod, rrule_id, "
142                         "has_alarm, system_type, updated, "
143                         "sync_data1, sync_data2, sync_data3, sync_data4, "
144                         "organizer_name, organizer_email, "
145                         "has_attendee, has_extended, "
146                         "freq, is_allday "
147                         ") VALUES ("
148                         "%d, "
149                         "%d, %d, "
150                         "?, ?, ?, ?, "
151                         "%d, %d, "
152                         "%d, ?, "
153                         "%d, "
154                         "%lf, %lf, "
155                         "strftime('%%s', 'now'), %lld, %d, "
156                         "%d, %lld, ?, ?, "
157                         "%d, %lld, ?, ?, "
158                         "strftime('%%s', 'now'), %d, "
159                         "%d, %d, %d, "
160                         "?, ?, ?, ?, "
161                         "?, ?, "
162                         "%d, %d, "
163                         "%d, %d) ",
164                 CAL_TABLE_SCHEDULE,
165                 CAL_SCH_TYPE_TODO, /*event->cal_type,*/
166                 input_ver, input_ver,
167                 todo->todo_status, todo->priority,
168                 todo->sensitivity,
169                 todo->calendar_id,
170                 todo->latitude, todo->longitude,
171                 todo->completed_time, todo->progress,
172                 todo->start.type, todo->start.type == CALENDAR_TIME_UTIME ? todo->start.time.utime : 0,
173                 todo->due.type, todo->due.type == CALENDAR_TIME_UTIME ? todo->due.time.utime : 0,
174                 0 < todo->freq ? 1 : 0,
175                 has_alarm,
176                 todo->system_type,
177                 todo->updated,
178                 (todo->attendee_list && 0 < todo->attendee_list->count) ? 1 : 0,
179                 (todo->extended_list && 0 < todo->extended_list->count) ? 1 : 0,
180                 todo->freq, is_allday);
181
182         ret = cal_db_util_query_prepare(query, &stmt);
183         if (CALENDAR_ERROR_NONE != ret) {
184                 /* LCOV_EXCL_START */
185                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
186                 SECURE("query[%s]", query);
187                 return ret;
188                 /* LCOV_EXCL_STOP */
189         }
190
191         int count = 1;
192
193         if (todo->summary)
194                 cal_db_util_stmt_bind_text(stmt, count, todo->summary);
195         count++;
196
197         if (todo->description)
198                 cal_db_util_stmt_bind_text(stmt, count, todo->description);
199         count++;
200
201         if (todo->location)
202                 cal_db_util_stmt_bind_text(stmt, count, todo->location);
203         count++;
204
205         if (todo->categories)
206                 cal_db_util_stmt_bind_text(stmt, count, todo->categories);
207         count++;
208
209         if (todo->uid)
210                 cal_db_util_stmt_bind_text(stmt, count, todo->uid);
211         count++;
212
213         if (CALENDAR_TIME_LOCALTIME == todo->start.type) {
214                 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME,
215                                 todo->start.time.date.year,
216                                 todo->start.time.date.month,
217                                 todo->start.time.date.mday,
218                                 todo->start.time.date.hour,
219                                 todo->start.time.date.minute,
220                                 todo->start.time.date.second);
221                 cal_db_util_stmt_bind_text(stmt, count, dtstart_datetime);
222         }
223         count++;
224
225         if (todo->start_tzid)
226                 cal_db_util_stmt_bind_text(stmt, count, todo->start_tzid);
227         count++;
228
229         if (CALENDAR_TIME_LOCALTIME == todo->due.type) {
230                 snprintf(dtend_datetime, sizeof(dtend_datetime), CAL_FORMAT_LOCAL_DATETIME,
231                                 todo->due.time.date.year,
232                                 todo->due.time.date.month,
233                                 todo->due.time.date.mday,
234                                 todo->due.time.date.hour,
235                                 todo->due.time.date.minute,
236                                 todo->due.time.date.second);
237                 cal_db_util_stmt_bind_text(stmt, count, dtend_datetime);
238         }
239         count++;
240
241         if (todo->due_tzid)
242                 cal_db_util_stmt_bind_text(stmt, count, todo->due_tzid);
243         count++;
244
245         if (todo->sync_data1)
246                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data1);
247         count++;
248         if (todo->sync_data2)
249                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data2);
250         count++;
251         if (todo->sync_data3)
252                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data3);
253         count++;
254         if (todo->sync_data4)
255                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data4);
256         count++;
257         if (todo->organizer_name)
258                 cal_db_util_stmt_bind_text(stmt, count, todo->organizer_name);
259         count++;
260         if (todo->organizer_email)
261                 cal_db_util_stmt_bind_text(stmt, count, todo->organizer_email);
262         count++;
263
264         ret = cal_db_util_stmt_step(stmt);
265         if (CALENDAR_ERROR_NONE != ret) {
266                 /* LCOV_EXCL_START */
267                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
268                 SECURE("query[%s]", query);
269                 sqlite3_finalize(stmt);
270                 return ret;
271                 /* LCOV_EXCL_STOP */
272         }
273
274         index = cal_db_util_last_insert_id();
275         sqlite3_finalize(stmt);
276
277         calendar_record_get_int(record, _calendar_todo.id, &tmp);
278         cal_record_set_int(record, _calendar_todo.id, index);
279         if (id)
280                 *id = index;
281
282         cal_db_rrule_get_rrule_from_record(record, &rrule);
283         cal_db_rrule_insert_record(index, rrule);
284
285         if (todo->alarm_list && 0 < todo->alarm_list->count) {
286                 ret = cal_db_alarm_insert_records(todo->alarm_list, index);
287                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_alarm_insert_records() Fail(%x)", ret);
288         }
289
290         if (todo->attendee_list && 0 < todo->attendee_list->count) {
291                 ret = cal_db_attendee_insert_records(todo->attendee_list, index);
292                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_attendee_insert_records() Fail(%x)", ret);
293         }
294
295         if (todo->extended_list && 0 < todo->extended_list->count) {
296                 DBG("insert extended");
297                 ret = cal_db_extended_insert_records(todo->extended_list, index, CALENDAR_RECORD_TYPE_TODO);
298                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_extended_insert_records() Fail(%x)", ret);
299         } else {
300                 DBG("No extended");
301         }
302
303         CAL_FREE(rrule);
304         cal_db_util_notify(CAL_NOTI_TYPE_TODO);
305
306         cal_record_set_int(record, _calendar_todo.id, tmp);
307
308         return CALENDAR_ERROR_NONE;
309 }
310
311 static int _cal_db_todo_get_record(int id, calendar_record_h* out_record)
312 {
313         char query[CAL_DB_SQL_MAX_LEN];
314         cal_todo_s *todo = NULL;
315         cal_rrule_s *rrule = NULL;
316         sqlite3_stmt *stmt = NULL;
317         int extended = 0;
318         calendar_record_h record_calendar;
319         calendar_book_sync_event_type_e sync_event_type = CALENDAR_BOOK_SYNC_EVENT_FOR_ME;
320         int ret = 0;
321
322         ret = calendar_record_create(_calendar_todo._uri, out_record);
323         if (CALENDAR_ERROR_NONE != ret) {
324                 /* LCOV_EXCL_START */
325                 ERR("calendar_record_create() Fail(%d)", ret);
326                 return CALENDAR_ERROR_OUT_OF_MEMORY;
327                 /* LCOV_EXCL_STOP */
328         }
329
330         todo =  (cal_todo_s*)(*out_record);
331
332         snprintf(query, sizeof(query), "SELECT "CAL_QUERY_SCHEDULE_A_ALL" FROM %s AS A "
333                         "WHERE id=%d AND (type = %d OR type = %d) AND calendar_id IN "
334                         "(select id from %s where deleted = 0)",
335                         CAL_TABLE_SCHEDULE,
336                         id, CALENDAR_BOOK_TYPE_TODO, CALENDAR_BOOK_TYPE_NONE,
337                         CAL_TABLE_CALENDAR);
338         ret = cal_db_util_query_prepare(query, &stmt);
339         if (CALENDAR_ERROR_NONE != ret) {
340                 /* LCOV_EXCL_START */
341                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
342                 SECURE("query[%s]", query);
343                 calendar_record_destroy(*out_record, true);
344                 *out_record = NULL;
345                 return ret;
346                 /* LCOV_EXCL_STOP */
347         }
348
349         ret = cal_db_util_stmt_step(stmt);
350         if (CAL_SQLITE_ROW != ret) {
351                 /* LCOV_EXCL_START */
352                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
353                 sqlite3_finalize(stmt);
354                 calendar_record_destroy(*out_record, true);
355                 *out_record = NULL;
356                 if (CALENDAR_ERROR_NONE == ret)
357                         return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
358                 return ret;
359                 /* LCOV_EXCL_STOP */
360         }
361
362         _cal_db_todo_get_stmt(stmt, false, *out_record, &extended);
363         sqlite3_finalize(stmt);
364         stmt = NULL;
365
366         ret = cal_db_get_record(_calendar_book._uri, todo->calendar_id, &record_calendar);
367         if (CALENDAR_ERROR_NONE == ret) {
368                 ret = calendar_record_get_int(record_calendar,
369                                 _calendar_book.sync_event, (int *)&sync_event_type);
370                 calendar_record_destroy(record_calendar, true);
371         }
372         if (todo->is_deleted == 1 && sync_event_type != CALENDAR_BOOK_SYNC_EVENT_FOR_EVERY_AND_REMAIN
373            ) {
374                 calendar_record_destroy(*out_record, true);
375                 *out_record = NULL;
376                 return CALENDAR_ERROR_DB_RECORD_NOT_FOUND;
377         }
378
379         if (CALENDAR_RECURRENCE_NONE != todo->freq) {
380                 ret = cal_db_rrule_get_rrule(todo->index, &rrule);
381                 if (CALENDAR_ERROR_NONE == ret) {
382                         cal_db_rrule_set_rrule_to_record(rrule, *out_record);
383                         CAL_FREE(rrule);
384                 }
385         }
386
387         if (todo->has_alarm == 1)
388                 cal_db_alarm_get_records(todo->index, todo->alarm_list);
389
390         if (todo->has_attendee == 1)
391                 cal_db_attendee_get_records(todo->index, todo->attendee_list);
392
393         if (extended == 1)
394                 cal_db_extended_get_records(todo->index, CALENDAR_RECORD_TYPE_TODO, todo->extended_list);
395
396         return CALENDAR_ERROR_NONE;
397 }
398
399 static int _cal_db_todo_update_record(calendar_record_h record)
400 {
401         char query[CAL_DB_SQL_MAX_LEN] = {0};
402         char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
403         char dtend_datetime[CAL_STR_SHORT_LEN32] = {0};
404         sqlite3_stmt *stmt = NULL;
405         cal_todo_s* todo =  (cal_todo_s*)(record);
406         cal_rrule_s *rrule = NULL;
407         int ret = 0;
408         int has_alarm = 0;
409
410         RETV_IF(NULL == todo, CALENDAR_ERROR_INVALID_PARAMETER);
411
412         if (cal_access_control_have_write_permission(todo->calendar_id) == false) {
413                 /* LCOV_EXCL_START */
414                 ERR("cal_access_control_have_write_permission() Fail");
415                 return CALENDAR_ERROR_PERMISSION_DENIED;
416                 /* LCOV_EXCL_STOP */
417         }
418
419         if (todo->common.properties_flags != NULL)
420                 return _cal_db_todo_update_dirty(record);
421
422         has_alarm = cal_db_alarm_has_alarm(todo->alarm_list);
423         int is_allday = 0;
424         if (CALENDAR_TIME_LOCALTIME == todo->start.type
425                         && (0 == todo->start.time.date.hour)
426                         && (0 == todo->start.time.date.minute)
427                         && (0 == todo->start.time.date.second)
428                         && (0 == todo->due.time.date.hour)
429                         && (0 == todo->due.time.date.minute)
430                         && (0 == todo->due.time.date.second)) {
431                 is_allday = 1;
432         }
433
434         snprintf(query, sizeof(query), "UPDATE %s SET "
435                         "changed_ver = %d,"
436                         "type = %d,"
437                         "summary = ?,"
438                         "description = ?,"
439                         "location = ?,"
440                         "categories = ?,"
441                         "task_status = %d,"
442                         "priority = %d,"
443                         "sensitivity = %d, "
444                         "uid = ?, "
445                         "calendar_id = %d, "
446                         "latitude = %lf,"
447                         "longitude = %lf,"
448                         "completed_time = %lld,"
449                         "progress = %d, "
450                         "dtstart_type = %d, "
451                         "dtstart_utime = %lld, "
452                         "dtstart_datetime = ?, "
453                         "dtstart_tzid = ?, "
454                         "dtend_type = %d, "
455                         "dtend_utime = %lld, "
456                         "dtend_datetime = ?, "
457                         "dtend_tzid = ?, "
458                         "last_mod = strftime('%%s', 'now'), "
459                         "has_alarm = %d, "
460                         "system_type = %d, "
461                         "updated = %d, "
462                         "sync_data1 = ?, "
463                         "sync_data2 = ?, "
464                         "sync_data3 = ?, "
465                         "sync_data4 = ?, "
466                         "organizer_name = ?, "
467                         "organizer_email = ?, "
468                         "has_attendee = %d,"
469                         "has_extended = %d, "
470                         "is_allday = %d "
471                         "WHERE id = %d;",
472                 CAL_TABLE_SCHEDULE,
473                 cal_db_util_get_next_ver(),
474                 CAL_SCH_TYPE_TODO,/*todo->cal_type,*/
475                 todo->todo_status,
476                 todo->priority,
477                 todo->sensitivity,
478                 todo->calendar_id,
479                 todo->latitude,
480                 todo->longitude,
481                 todo->completed_time,
482                 todo->progress,
483                 todo->start.type,
484                 todo->start.type == CALENDAR_TIME_UTIME ? todo->start.time.utime : 0,
485                 todo->due.type,
486                 todo->due.type == CALENDAR_TIME_UTIME ? todo->due.time.utime : 0,
487                 has_alarm,
488                 todo->system_type,
489                 todo->updated,
490                 (todo->attendee_list && 0 < todo->attendee_list->count) ? 1 : 0,
491                 (todo->extended_list && 0 < todo->extended_list->count) ? 1 : 0,
492                 is_allday,
493                 todo->index);
494
495         ret = cal_db_util_query_prepare(query, &stmt);
496         if (CALENDAR_ERROR_NONE != ret) {
497                 /* LCOV_EXCL_START */
498                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
499                 SECURE("query[%s]", query);
500                 return ret;
501                 /* LCOV_EXCL_STOP */
502         }
503
504         int count = 1;
505
506         if (todo->summary)
507                 cal_db_util_stmt_bind_text(stmt, count, todo->summary);
508         count++;
509
510         if (todo->description)
511                 cal_db_util_stmt_bind_text(stmt, count, todo->description);
512         count++;
513
514         if (todo->location)
515                 cal_db_util_stmt_bind_text(stmt, count, todo->location);
516         count++;
517
518         if (todo->categories)
519                 cal_db_util_stmt_bind_text(stmt, count, todo->categories);
520         count++;
521
522         if (todo->uid)
523                 cal_db_util_stmt_bind_text(stmt, count, todo->uid);
524         count++;
525
526         if (CALENDAR_TIME_LOCALTIME == todo->start.type) {
527                 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME,
528                                 todo->start.time.date.year,
529                                 todo->start.time.date.month,
530                                 todo->start.time.date.mday,
531                                 todo->start.time.date.hour,
532                                 todo->start.time.date.minute,
533                                 todo->start.time.date.second);
534                 cal_db_util_stmt_bind_text(stmt, count, dtstart_datetime);
535         }
536         count++;
537
538         if (todo->start_tzid)
539                 cal_db_util_stmt_bind_text(stmt, count, todo->start_tzid);
540         count++;
541
542         if (CALENDAR_TIME_LOCALTIME == todo->due.type) {
543                 snprintf(dtend_datetime, sizeof(dtend_datetime), CAL_FORMAT_LOCAL_DATETIME,
544                                 todo->due.time.date.year,
545                                 todo->due.time.date.month,
546                                 todo->due.time.date.mday,
547                                 todo->due.time.date.hour,
548                                 todo->due.time.date.minute,
549                                 todo->due.time.date.second);
550                 cal_db_util_stmt_bind_text(stmt, count, dtend_datetime);
551         }
552         count++;
553
554         if (todo->due_tzid)
555                 cal_db_util_stmt_bind_text(stmt, count, todo->due_tzid);
556         count++;
557
558         if (todo->sync_data1)
559                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data1);
560         count++;
561         if (todo->sync_data2)
562                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data2);
563         count++;
564         if (todo->sync_data3)
565                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data3);
566         count++;
567         if (todo->sync_data4)
568                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data4);
569         count++;
570         if (todo->organizer_name)
571                 cal_db_util_stmt_bind_text(stmt, count, todo->organizer_name);
572         count++;
573         if (todo->organizer_email)
574                 cal_db_util_stmt_bind_text(stmt, count, todo->organizer_email);
575         count++;
576
577         ret = cal_db_util_stmt_step(stmt);
578         sqlite3_finalize(stmt);
579         if (CALENDAR_ERROR_NONE != ret) {
580                 /* LCOV_EXCL_START */
581                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
582                 return ret;
583                 /* LCOV_EXCL_STOP */
584         }
585
586         cal_db_rrule_get_rrule_from_record(record, &rrule);
587         cal_db_rrule_update_record(todo->index, rrule);
588         CAL_FREE(rrule);
589
590         cal_db_alarm_delete_with_id(todo->index);
591         cal_db_attendee_delete_with_id(todo->index);
592         cal_db_extended_delete_with_id(todo->index, CALENDAR_RECORD_TYPE_TODO);
593
594         if (todo->alarm_list && 0 < todo->alarm_list->count) {
595                 ret = cal_db_alarm_insert_records(todo->alarm_list, todo->index);
596                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_alarm_insert_records() Fail(%d)", ret);
597         }
598
599         if (todo->attendee_list && 0 < todo->attendee_list->count) {
600                 ret = cal_db_attendee_insert_records(todo->attendee_list, todo->index);
601                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_attendee_insert_records() Fail(%d)", ret);
602         }
603
604
605         if (todo->extended_list && 0 < todo->extended_list->count) {
606                 DBG("insert extended");
607                 ret = cal_db_extended_insert_records(todo->extended_list, todo->index, CALENDAR_RECORD_TYPE_TODO);
608                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_extended_insert_records() Fail(%d)", ret);
609         }
610
611         cal_db_util_notify(CAL_NOTI_TYPE_TODO);
612
613         return CALENDAR_ERROR_NONE;
614 }
615
616 static int _cal_db_todo_delete_record(int id)
617 {
618         int ret = 0;
619         int calendar_book_id = 0;
620         char query[CAL_DB_SQL_MAX_LEN] = {0};
621         int created_ver = 0;
622         calendar_book_sync_event_type_e sync_event_type = CALENDAR_BOOK_SYNC_EVENT_FOR_ME;
623
624         RETVM_IF(id < 0, CALENDAR_ERROR_INVALID_PARAMETER, "id(%d) < 0", id);
625
626         ret = _cal_db_todo_get_deleted_data(id, &calendar_book_id, &created_ver);
627         if (CALENDAR_ERROR_NONE != ret) {
628                 DBG("_cal_db_event_get_deleted_data() Fail");
629                 return ret;
630         }
631
632         if (cal_access_control_have_write_permission(calendar_book_id) == false) {
633                 /* LCOV_EXCL_START */
634                 ERR("cal_access_control_have_write_permission() Fail");
635                 return CALENDAR_ERROR_PERMISSION_DENIED;
636                 /* LCOV_EXCL_STOP */
637         }
638
639         snprintf(query, sizeof(query), "SELECT sync_event FROM %s WHERE id = %d ",
640                         CAL_TABLE_CALENDAR, calendar_book_id);
641         ret = cal_db_util_query_get_first_int_result(query, NULL, (int *)&sync_event_type);
642         if (CALENDAR_ERROR_NONE != ret) {
643                 /* LCOV_EXCL_START */
644                 ERR("cal_db_util_query_get_first_int_result() Fail");
645                 return ret;
646                 /* LCOV_EXCL_STOP */
647         }
648         DBG("sync_event_type(%d)", sync_event_type);
649
650         if (sync_event_type == CALENDAR_BOOK_SYNC_EVENT_FOR_EVERY_AND_REMAIN) {
651                 DBG("set is_delete");
652                 snprintf(query, sizeof(query), "UPDATE %s SET is_deleted = 1, changed_ver = %d, "
653                                 "last_mod = strftime('%%s','now') WHERE id = %d ",
654                                 CAL_TABLE_SCHEDULE, cal_db_util_get_next_ver(), id);
655
656                 ret = cal_db_util_query_exec(query);
657                 if (CALENDAR_ERROR_NONE != ret) {
658                         /* LCOV_EXCL_START */
659                         ERR("cal_db_util_query_exec() Fail(%d)", ret);
660                         SECURE("[%s]", query);
661                         return ret;
662                         /* LCOV_EXCL_STOP */
663                 }
664                 DBG("attendee, alarm and rrule will be deleted by trigger after sync clean");
665         } else {
666                 cal_db_util_get_next_ver();
667
668                 DBG("delete event");
669                 snprintf(query, sizeof(query), "DELETE FROM %s WHERE id = %d ", CAL_TABLE_SCHEDULE, id);
670                 ret = cal_db_util_query_exec(query);
671                 if (CALENDAR_ERROR_NONE != ret) {
672                         /* LCOV_EXCL_START */
673                         ERR("cal_db_util_query_exec() Fail(%d)", ret);
674                         SECURE("[%s]", query);
675                         return ret;
676                         /* LCOV_EXCL_STOP */
677                 }
678                 DBG("attendee, alarm and rrule is deleted by trigger");
679         }
680         cal_db_util_notify(CAL_NOTI_TYPE_TODO);
681
682         return CALENDAR_ERROR_NONE;
683 }
684
685 static int _cal_db_todo_replace_record(calendar_record_h record, int id)
686 {
687         int ret = CALENDAR_ERROR_NONE;
688         char query[CAL_DB_SQL_MAX_LEN] = {0};
689         char dtstart_datetime[CAL_STR_SHORT_LEN32] = {0};
690         char dtend_datetime[CAL_STR_SHORT_LEN32] = {0};
691         sqlite3_stmt *stmt = NULL;
692         cal_todo_s* todo =  (cal_todo_s*)(record);
693         cal_rrule_s *rrule = NULL;
694         int has_alarm = 0;
695
696         RETV_IF(NULL == todo, CALENDAR_ERROR_INVALID_PARAMETER);
697         todo->index = id;
698
699         if (cal_access_control_have_write_permission(todo->calendar_id) == false) {
700                 /* LCOV_EXCL_START */
701                 ERR("cal_access_control_have_write_permission() Fail");
702                 return CALENDAR_ERROR_PERMISSION_DENIED;
703                 /* LCOV_EXCL_STOP */
704         }
705
706         if (todo->common.properties_flags)
707                 return _cal_db_todo_update_dirty(record);
708
709         int is_allday = 0;
710         if (CALENDAR_TIME_LOCALTIME == todo->start.type
711                         && (0 == todo->start.time.date.hour)
712                         && (0 == todo->start.time.date.minute)
713                         && (0 == todo->start.time.date.second)
714                         && (0 == todo->due.time.date.hour)
715                         && (0 == todo->due.time.date.minute)
716                         && (0 == todo->due.time.date.second)) {
717                 is_allday = 1;
718         }
719
720         has_alarm = cal_db_alarm_has_alarm(todo->alarm_list);
721         snprintf(query, sizeof(query), "UPDATE %s SET "
722                         "changed_ver = %d,"
723                         "type = %d,"
724                         "summary = ?,"
725                         "description = ?,"
726                         "location = ?,"
727                         "categories = ?,"
728                         "task_status = %d,"
729                         "priority = %d,"
730                         "sensitivity = %d, "
731                         "uid = ?, "
732                         "calendar_id = %d, "
733                         "latitude = %lf,"
734                         "longitude = %lf,"
735                         "completed_time = %lld,"
736                         "progress = %d, "
737                         "dtstart_type = %d, "
738                         "dtstart_utime = %lld, "
739                         "dtstart_datetime = ?, "
740                         "dtstart_tzid = ?, "
741                         "dtend_type = %d, "
742                         "dtend_utime = %lld, "
743                         "dtend_datetime = ?, "
744                         "dtend_tzid = ?, "
745                         "last_mod = strftime('%%s', 'now'), "
746                         "has_alarm = %d, "
747                         "system_type = %d, "
748                         "updated = %d, "
749                         "sync_data1 = ?, "
750                         "sync_data2 = ?, "
751                         "sync_data3 = ?, "
752                         "sync_data4 = ?, "
753                         "organizer_name = ?, "
754                         "organizer_email = ?, "
755                         "has_attendee = %d,"
756                         "has_extended = %d, "
757                         "is_allday = %d "
758                         "WHERE id = %d;",
759                 CAL_TABLE_SCHEDULE,
760                 cal_db_util_get_next_ver(),
761                 CAL_SCH_TYPE_TODO,/*todo->cal_type,*/
762                 todo->todo_status,
763                 todo->priority,
764                 todo->sensitivity,
765                 todo->calendar_id,
766                 todo->latitude,
767                 todo->longitude,
768                 todo->completed_time,
769                 todo->progress,
770                 todo->start.type,
771                 todo->start.type == CALENDAR_TIME_UTIME ? todo->start.time.utime : 0,
772                 todo->due.type,
773                 todo->due.type == CALENDAR_TIME_UTIME ? todo->due.time.utime : 0,
774                 has_alarm,
775                 todo->system_type,
776                 todo->updated,
777                 (todo->attendee_list && 0 < todo->attendee_list->count) ? 1 : 0,
778                 (todo->extended_list && 0 < todo->extended_list->count) ? 1 : 0,
779                 is_allday,
780                 id);
781
782         ret = cal_db_util_query_prepare(query, &stmt);
783         if (CALENDAR_ERROR_NONE != ret) {
784                 /* LCOV_EXCL_START */
785                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
786                 SECURE("query[%s]", query);
787                 return ret;
788                 /* LCOV_EXCL_STOP */
789         }
790
791         int count = 1;
792
793         if (todo->summary)
794                 cal_db_util_stmt_bind_text(stmt, count, todo->summary);
795         count++;
796
797         if (todo->description)
798                 cal_db_util_stmt_bind_text(stmt, count, todo->description);
799         count++;
800
801         if (todo->location)
802                 cal_db_util_stmt_bind_text(stmt, count, todo->location);
803         count++;
804
805         if (todo->categories)
806                 cal_db_util_stmt_bind_text(stmt, count, todo->categories);
807         count++;
808
809         if (todo->uid)
810                 cal_db_util_stmt_bind_text(stmt, count, todo->uid);
811         count++;
812
813         if (CALENDAR_TIME_LOCALTIME == todo->start.type) {
814                 snprintf(dtstart_datetime, sizeof(dtstart_datetime), CAL_FORMAT_LOCAL_DATETIME,
815                                 todo->start.time.date.year,
816                                 todo->start.time.date.month,
817                                 todo->start.time.date.mday,
818                                 todo->start.time.date.hour,
819                                 todo->start.time.date.minute,
820                                 todo->start.time.date.second);
821                 cal_db_util_stmt_bind_text(stmt, count, dtstart_datetime);
822         }
823         count++;
824
825         if (todo->start_tzid)
826                 cal_db_util_stmt_bind_text(stmt, count, todo->start_tzid);
827         count++;
828
829         if (CALENDAR_TIME_LOCALTIME == todo->due.type) {
830                 snprintf(dtend_datetime, sizeof(dtend_datetime), CAL_FORMAT_LOCAL_DATETIME,
831                                 todo->due.time.date.year,
832                                 todo->due.time.date.month,
833                                 todo->due.time.date.mday,
834                                 todo->due.time.date.hour,
835                                 todo->due.time.date.minute,
836                                 todo->due.time.date.second);
837                 cal_db_util_stmt_bind_text(stmt, count, dtend_datetime);
838         }
839         count++;
840
841         if (todo->due_tzid)
842                 cal_db_util_stmt_bind_text(stmt, count, todo->due_tzid);
843         count++;
844
845         if (todo->sync_data1)
846                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data1);
847         count++;
848         if (todo->sync_data2)
849                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data2);
850         count++;
851         if (todo->sync_data3)
852                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data3);
853         count++;
854         if (todo->sync_data4)
855                 cal_db_util_stmt_bind_text(stmt, count, todo->sync_data4);
856         count++;
857         if (todo->organizer_name)
858                 cal_db_util_stmt_bind_text(stmt, count, todo->organizer_name);
859         count++;
860         if (todo->organizer_email)
861                 cal_db_util_stmt_bind_text(stmt, count, todo->organizer_email);
862         count++;
863
864         ret = cal_db_util_stmt_step(stmt);
865         sqlite3_finalize(stmt);
866         if (CALENDAR_ERROR_NONE != ret) {
867                 /* LCOV_EXCL_START */
868                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
869                 return ret;
870                 /* LCOV_EXCL_STOP */
871         }
872
873         cal_db_rrule_get_rrule_from_record(record, &rrule);
874         cal_db_rrule_update_record(id, rrule);
875         CAL_FREE(rrule);
876
877         cal_db_alarm_delete_with_id(id);
878         cal_db_attendee_delete_with_id(id);
879         cal_db_extended_delete_with_id(id, CALENDAR_RECORD_TYPE_TODO);
880
881         if (todo->alarm_list && 0 < todo->alarm_list->count) {
882                 ret = cal_db_alarm_insert_records(todo->alarm_list, id);
883                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_alarm_insert_records() Fail(%x)", ret);
884         }
885
886         if (todo->attendee_list && 0 < todo->attendee_list->count) {
887                 ret = cal_db_attendee_insert_records(todo->attendee_list, id);
888                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_attendee_insert_records() Fail(%x)", ret);
889         }
890
891         if (todo->extended_list && 0 < todo->extended_list->count) {
892                 DBG("insert extended");
893                 ret = cal_db_extended_insert_records(todo->extended_list, id, CALENDAR_RECORD_TYPE_TODO);
894                 WARN_IF(CALENDAR_ERROR_NONE != ret, "cal_db_extended_insert_records() Fail(%d)", ret);
895         }
896
897         cal_db_util_notify(CAL_NOTI_TYPE_TODO);
898
899         return CALENDAR_ERROR_NONE;
900 }
901
902 static int _cal_db_todo_get_all_records(int offset, int limit, calendar_list_h* out_list)
903 {
904         int ret = CALENDAR_ERROR_NONE;
905         char offsetquery[CAL_DB_SQL_MAX_LEN] = {0};
906         char limitquery[CAL_DB_SQL_MAX_LEN] = {0};
907         sqlite3_stmt *stmt = NULL;
908
909         RETV_IF(NULL == out_list, CALENDAR_ERROR_INVALID_PARAMETER);
910
911         ret = calendar_list_create(out_list);
912         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_list_create() Fail(%d)", ret);
913
914         if (0 < offset)
915                 snprintf(offsetquery, sizeof(offsetquery), "OFFSET %d", offset);
916
917         if (0 < limit)
918                 snprintf(limitquery, sizeof(limitquery), "LIMIT %d", limit);
919
920         char *query_str = NULL;
921         cal_db_append_string(&query_str, "SELECT * FROM");
922         cal_db_append_string(&query_str, CAL_VIEW_TABLE_TODO);
923         cal_db_append_string(&query_str, limitquery);
924         cal_db_append_string(&query_str, offsetquery);
925
926         ret = cal_db_util_query_prepare(query_str, &stmt);
927         if (CALENDAR_ERROR_NONE != ret) {
928                 /* LCOV_EXCL_START */
929                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
930                 SECURE("query[%s]", query_str);
931                 calendar_list_destroy(*out_list, true);
932                 *out_list = NULL;
933                 CAL_FREE(query_str);
934                 return ret;
935                 /* LCOV_EXCL_STOP */
936         }
937
938         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
939                 calendar_record_h record;
940                 int extended = 0;
941                 ret = calendar_record_create(_calendar_todo._uri, &record);
942                 if (CALENDAR_ERROR_NONE != ret) {
943                         /* LCOV_EXCL_START */
944                         calendar_list_destroy(*out_list, true);
945                         *out_list = NULL;
946                         sqlite3_finalize(stmt);
947                         CAL_FREE(query_str);
948                         return ret;
949                         /* LCOV_EXCL_STOP */
950                 }
951                 _cal_db_todo_get_stmt(stmt, true, record, &extended);
952
953                 /* child */
954                 int has_attendee = 0, has_alarm = 0;
955                 int record_id = 0;
956                 cal_todo_s* ptodo = (cal_todo_s*) record;
957                 calendar_record_get_int(record, _calendar_todo.id, &record_id);
958                 if (CALENDAR_ERROR_NONE ==  calendar_record_get_int(record, _calendar_todo.has_attendee, &has_attendee)) {
959                         if (has_attendee == 1)
960                                 cal_db_attendee_get_records(record_id, ptodo->attendee_list);
961                 }
962                 if (CALENDAR_ERROR_NONE ==  calendar_record_get_int(record, _calendar_todo.has_alarm, &has_alarm)) {
963                         if (has_alarm == 1)
964                                 cal_db_alarm_get_records(record_id, ptodo->alarm_list);
965                 }
966
967                 if (extended == 1)
968                         cal_db_extended_get_records(record_id, CALENDAR_RECORD_TYPE_TODO, ptodo->extended_list);
969
970                 ret = calendar_list_add(*out_list, record);
971                 if (CALENDAR_ERROR_NONE != ret) {
972                         /* LCOV_EXCL_START */
973                         calendar_list_destroy(*out_list, true);
974                         *out_list = NULL;
975                         calendar_record_destroy(record, true);
976                         sqlite3_finalize(stmt);
977                         CAL_FREE(query_str);
978                         return ret;
979                         /* LCOV_EXCL_STOP */
980                 }
981         }
982         sqlite3_finalize(stmt);
983         CAL_FREE(query_str);
984
985         return CALENDAR_ERROR_NONE;
986 }
987
988 static int _cal_db_todo_get_records_with_query(calendar_query_h query, int offset, int limit, calendar_list_h* out_list)
989 {
990         cal_query_s *que = NULL;
991         int ret = CALENDAR_ERROR_NONE;
992         char *condition = NULL;
993         char *projection = NULL;
994         GSList *bind_text = NULL, *cursor = NULL;
995         sqlite3_stmt *stmt = NULL;
996         int i = 0;
997         char *table_name;
998
999         que = (cal_query_s *)query;
1000
1001         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_TODO)) {
1002                 table_name = cal_strdup(CAL_VIEW_TABLE_TODO);
1003         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_TODO_CALENDAR)) {
1004                 table_name = cal_strdup(CAL_VIEW_TABLE_TODO_CALENDAR);
1005         } else {
1006                 /* LCOV_EXCL_START */
1007                 ERR("uri(%s) not support get records with query", que->view_uri);
1008                 return CALENDAR_ERROR_INVALID_PARAMETER;
1009                 /* LCOV_EXCL_STOP */
1010         }
1011
1012         /* make filter */
1013         if (que->filter) {
1014                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
1015                 if (CALENDAR_ERROR_NONE != ret) {
1016                         /* LCOV_EXCL_START */
1017                         ERR("cal_db_query_create_condition() Fail(%d), ret");
1018                         CAL_FREE(table_name);
1019                         return ret;
1020                         /* LCOV_EXCL_STOP */
1021                 }
1022         }
1023
1024         /* make: projection */
1025         ret = cal_db_query_create_projection(query, &projection);
1026
1027         char *query_str = NULL;
1028
1029         /* query: projection */
1030         if (projection) {
1031                 cal_db_append_string(&query_str, "SELECT");
1032                 cal_db_append_string(&query_str, projection);
1033                 cal_db_append_string(&query_str, "FROM");
1034                 cal_db_append_string(&query_str, table_name);
1035                 CAL_FREE(projection);
1036         } else {
1037                 cal_db_append_string(&query_str, "SELECT * FROM");
1038                 cal_db_append_string(&query_str, table_name);
1039         }
1040         CAL_FREE(table_name);
1041
1042         /* query: condition */
1043         if (condition) {
1044                 cal_db_append_string(&query_str, "WHERE (");
1045                 cal_db_append_string(&query_str, condition);
1046                 cal_db_append_string(&query_str, ")");
1047         }
1048
1049         /* order */
1050         char *order = NULL;
1051         ret = cal_db_query_create_order(query, condition, &order);
1052         if (order) {
1053                 cal_db_append_string(&query_str, order);
1054                 CAL_FREE(order);
1055         }
1056         CAL_FREE(condition);
1057
1058         /* limit, offset */
1059         char buf[CAL_STR_SHORT_LEN32] = {0};
1060         if (0 < limit) {
1061                 snprintf(buf, sizeof(buf), "LIMIT %d", limit);
1062                 cal_db_append_string(&query_str, buf);
1063
1064                 if (0 < offset) {
1065                         snprintf(buf, sizeof(buf), "OFFSET %d", offset);
1066                         cal_db_append_string(&query_str, buf);
1067                 }
1068         }
1069
1070         /* query */
1071         ret = cal_db_util_query_prepare(query_str, &stmt);
1072         if (CALENDAR_ERROR_NONE != ret) {
1073                 /* LCOV_EXCL_START */
1074                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1075                 SECURE("query[%s]", query_str);
1076                 if (bind_text) {
1077                         g_slist_free_full(bind_text, free);
1078                         bind_text = NULL;
1079                 }
1080                 free(query_str);
1081                 return ret;
1082                 /* LCOV_EXCL_STOP */
1083         }
1084
1085         /* bind text */
1086         if (bind_text) {
1087                 g_slist_length(bind_text);
1088                 for (cursor = bind_text, i = 1; cursor; cursor = cursor->next, i++)
1089                         cal_db_util_stmt_bind_text(stmt, i, cursor->data);
1090         }
1091
1092         ret = calendar_list_create(out_list);
1093         if (CALENDAR_ERROR_NONE != ret) {
1094                 /* LCOV_EXCL_START */
1095                 ERR("calendar_list_create() Fail");
1096                 if (bind_text) {
1097                         g_slist_free_full(bind_text, free);
1098                         bind_text = NULL;
1099                 }
1100                 sqlite3_finalize(stmt);
1101                 CAL_FREE(query_str);
1102                 return ret;
1103                 /* LCOV_EXCL_STOP */
1104         }
1105
1106         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
1107                 calendar_record_h record;
1108                 int extended = 1;
1109                 int attendee = 1, alarm = 1;
1110                 ret = calendar_record_create(_calendar_todo._uri, &record);
1111                 if (CALENDAR_ERROR_NONE != ret) {
1112                         /* LCOV_EXCL_START */
1113                         calendar_list_destroy(*out_list, true);
1114                         *out_list = NULL;
1115
1116                         if (bind_text) {
1117                                 g_slist_free_full(bind_text, free);
1118                                 bind_text = NULL;
1119                         }
1120                         sqlite3_finalize(stmt);
1121                         CAL_FREE(query_str);
1122                         return ret;
1123                         /* LCOV_EXCL_STOP */
1124                 }
1125                 if (0 < que->projection_count) {
1126                         cal_record_set_projection(record,
1127                                         que->projection, que->projection_count, que->property_count);
1128
1129                         _cal_db_todo_get_projection_stmt(stmt,
1130                                         que->projection, que->projection_count,
1131                                         record);
1132                 } else {
1133                         cal_todo_s *todo = NULL;
1134                         _cal_db_todo_get_stmt(stmt, true, record, &extended);
1135                         todo = (cal_todo_s*)(record);
1136                         if (todo) {
1137                                 attendee = todo->has_attendee;
1138                                 alarm = todo->has_alarm;
1139                         }
1140                 }
1141
1142                 /* child */
1143                 if (cal_db_query_find_projection_property(query, CAL_PROPERTY_TODO_CALENDAR_ALARM) == true && alarm == 1) {
1144                         cal_todo_s* todo = (cal_todo_s*) record;
1145                         cal_db_alarm_get_records(todo->index, todo->alarm_list);
1146                 }
1147                 if (cal_db_query_find_projection_property(query, CAL_PROPERTY_TODO_CALENDAR_ATTENDEE) == true && attendee == 1) {
1148                         cal_todo_s* todo = (cal_todo_s*) record;
1149                         cal_db_attendee_get_records(todo->index, todo->attendee_list);
1150                 }
1151                 if (cal_db_query_find_projection_property(query, CAL_PROPERTY_TODO_EXTENDED) == true && extended == 1) {
1152                         cal_todo_s* todo = (cal_todo_s*) record;
1153                         cal_db_extended_get_records(todo->index, CALENDAR_RECORD_TYPE_TODO, todo->extended_list);
1154                 }
1155
1156                 ret = calendar_list_add(*out_list, record);
1157                 if (CALENDAR_ERROR_NONE != ret) {
1158                         /* LCOV_EXCL_START */
1159                         calendar_list_destroy(*out_list, true);
1160                         *out_list = NULL;
1161                         calendar_record_destroy(record, true);
1162
1163                         if (bind_text) {
1164                                 g_slist_free_full(bind_text, free);
1165                                 bind_text = NULL;
1166                         }
1167                         sqlite3_finalize(stmt);
1168                         CAL_FREE(query_str);
1169                         return ret;
1170                         /* LCOV_EXCL_STOP */
1171                 }
1172         }
1173
1174         if (bind_text) {
1175                 g_slist_free_full(bind_text, free);
1176                 bind_text = NULL;
1177         }
1178
1179         sqlite3_finalize(stmt);
1180         CAL_FREE(query_str);
1181
1182         return CALENDAR_ERROR_NONE;
1183 }
1184
1185 static int _cal_db_todo_delete_records(int ids[], int count)
1186 {
1187         int ret = 0;
1188         int i = 0;
1189         for (i = 0; i < count; i++) {
1190                 ret = _cal_db_todo_delete_record(ids[i]);
1191                 if (CALENDAR_ERROR_NONE != ret) {
1192                         /* LCOV_EXCL_START */
1193                         ERR("_cal_db_todo_delete_record() Fail(%d)", ret);
1194                         return CALENDAR_ERROR_DB_FAILED;
1195                         /* LCOV_EXCL_STOP */
1196                 }
1197         }
1198         return CALENDAR_ERROR_NONE;
1199 }
1200
1201 static int _cal_db_todo_get_count(int *out_count)
1202 {
1203         RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
1204
1205         char *query_str = NULL;
1206         cal_db_append_string(&query_str, "SELECT count(*) FROM");
1207         cal_db_append_string(&query_str, CAL_VIEW_TABLE_TODO);
1208
1209         int ret = 0;
1210         int count = 0;
1211         ret = cal_db_util_query_get_first_int_result(query_str, NULL, &count);
1212         if (CALENDAR_ERROR_NONE != ret) {
1213                 /* LCOV_EXCL_START */
1214                 ERR("cal_db_util_query_get_first_int_result() Fail");
1215                 CAL_FREE(query_str);
1216                 return ret;
1217                 /* LCOV_EXCL_STOP */
1218         }
1219         DBG("count(%d) str[%s]", count, query_str);
1220         CAL_FREE(query_str);
1221
1222         *out_count = count;
1223         return CALENDAR_ERROR_NONE;
1224 }
1225
1226 static int _cal_db_todo_get_count_with_query(calendar_query_h query, int *out_count)
1227 {
1228         cal_query_s *que = NULL;
1229         int ret = CALENDAR_ERROR_NONE;
1230         char *condition = NULL;
1231         char *table_name;
1232         int count = 0;
1233         GSList *bind_text = NULL;
1234
1235         que = (cal_query_s *)query;
1236
1237         if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_TODO)) {
1238                 table_name = cal_strdup(CAL_VIEW_TABLE_TODO);
1239         } else if (CAL_STRING_EQUAL == strcmp(que->view_uri, CALENDAR_VIEW_TODO_CALENDAR)) {
1240                 table_name = cal_strdup(CAL_VIEW_TABLE_TODO_CALENDAR);
1241         } else {
1242                 /* LCOV_EXCL_START */
1243                 ERR("uri(%s) not support get records with query", que->view_uri);
1244                 return CALENDAR_ERROR_INVALID_PARAMETER;
1245                 /* LCOV_EXCL_STOP */
1246         }
1247
1248         /* make filter */
1249         if (que->filter) {
1250                 ret = cal_db_query_create_condition(query, &condition, &bind_text);
1251                 if (CALENDAR_ERROR_NONE != ret) {
1252                         /* LCOV_EXCL_START */
1253                         ERR("cal_db_query_create_condition() Fail(%d), ret");
1254                         CAL_FREE(table_name);
1255                         return ret;
1256                         /* LCOV_EXCL_STOP */
1257                 }
1258         }
1259
1260         char *query_str = NULL;
1261         /* query: select */
1262         cal_db_append_string(&query_str, "SELECT count(*) FROM");
1263         cal_db_append_string(&query_str, table_name);
1264         CAL_FREE(table_name);
1265
1266         /* query: condition */
1267         if (condition) {
1268                 cal_db_append_string(&query_str,  "WHERE (");
1269                 cal_db_append_string(&query_str, condition);
1270                 cal_db_append_string(&query_str, ")");
1271                 CAL_FREE(condition);
1272         }
1273
1274         /* query */
1275         ret = cal_db_util_query_get_first_int_result(query_str, bind_text, &count);
1276         if (CALENDAR_ERROR_NONE != ret) {
1277                 /* LCOV_EXCL_START */
1278                 ERR("cal_db_util_query_get_first_int_result() Fail");
1279                 if (bind_text) {
1280                         g_slist_free_full(bind_text, free);
1281                         bind_text = NULL;
1282                 }
1283                 CAL_FREE(query_str);
1284                 return ret;
1285                 /* LCOV_EXCL_STOP */
1286         }
1287         DBG("count(%d) str[%s]", count, query_str);
1288
1289         if (out_count) *out_count = count;
1290         if (bind_text) {
1291                 g_slist_free_full(bind_text, free);
1292                 bind_text = NULL;
1293         }
1294
1295         CAL_FREE(query_str);
1296         return CALENDAR_ERROR_NONE;
1297 }
1298
1299 static void _cal_db_todo_get_stmt(sqlite3_stmt *stmt, bool is_view_table, calendar_record_h record, int *extended)
1300 {
1301         cal_todo_s *todo = NULL;
1302         const unsigned char *temp;
1303         int count = 0;
1304
1305         todo = (cal_todo_s*)(record);
1306
1307         todo->index = sqlite3_column_int(stmt, count++);
1308         sqlite3_column_int(stmt, count++);
1309
1310         temp = sqlite3_column_text(stmt, count++);
1311         todo->summary = cal_strdup((const char*)temp);
1312         temp = sqlite3_column_text(stmt, count++);
1313         todo->description = cal_strdup((const char*)temp);
1314
1315         temp = sqlite3_column_text(stmt, count++);
1316         todo->location = cal_strdup((const char*)temp);
1317
1318         temp = sqlite3_column_text(stmt, count++);
1319         todo->categories = cal_strdup((const char*)temp);
1320
1321         sqlite3_column_text(stmt, count++);
1322
1323         todo->todo_status = sqlite3_column_int(stmt, count++);
1324         todo->priority = sqlite3_column_int(stmt, count++);
1325         sqlite3_column_int(stmt, count++);
1326         sqlite3_column_int(stmt, count++);
1327         sqlite3_column_int(stmt, count++);
1328         todo->sensitivity = sqlite3_column_int(stmt, count++);
1329
1330         temp = sqlite3_column_text(stmt, count++);
1331         todo->uid = cal_strdup((const char*)temp);
1332
1333         temp = sqlite3_column_text(stmt, count++);
1334         todo->organizer_name = cal_strdup((const char*)temp);
1335
1336         temp = sqlite3_column_text(stmt, count++);
1337         todo->organizer_email = cal_strdup((const char*)temp);
1338
1339         sqlite3_column_int(stmt, count++);
1340
1341         todo->calendar_id = sqlite3_column_int(stmt, count++);
1342
1343         sqlite3_column_int(stmt, count++);
1344
1345         todo->latitude = sqlite3_column_double(stmt, count++);
1346         todo->longitude = sqlite3_column_double(stmt, count++);
1347         sqlite3_column_int(stmt, count++);
1348
1349         todo->created_time = sqlite3_column_int64(stmt, count++);
1350
1351         todo->completed_time = sqlite3_column_int64(stmt, count++);
1352
1353         todo->progress = sqlite3_column_int(stmt, count++);
1354
1355         sqlite3_column_int(stmt, count++);
1356         sqlite3_column_int(stmt, count++);
1357         todo->is_deleted = sqlite3_column_int(stmt, count++);
1358
1359         todo->start.type = sqlite3_column_int(stmt, count++);
1360
1361         if (todo->start.type == CALENDAR_TIME_UTIME) {
1362                 todo->start.time.utime = sqlite3_column_int64(stmt, count++);
1363                 count++; /* dtstart_datetime */
1364         } else {
1365                 count++; /* dtstart_utime */
1366                 temp = sqlite3_column_text(stmt, count++);
1367                 if (temp) {
1368                         sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(todo->start.time.date.year),
1369                                         &(todo->start.time.date.month), &(todo->start.time.date.mday),
1370                                         &(todo->start.time.date.hour), &(todo->start.time.date.minute),
1371                                         &(todo->start.time.date.second));
1372                 }
1373         }
1374
1375         temp = sqlite3_column_text(stmt, count++);
1376         todo->start_tzid = cal_strdup((const char*)temp);
1377         todo->due.type = sqlite3_column_int(stmt, count++);
1378         if (todo->due.type == CALENDAR_TIME_UTIME) {
1379                 todo->due.time.utime = sqlite3_column_int64(stmt, count++);
1380                 count++; /* datatime */
1381         } else {
1382                 count++;
1383                 temp = sqlite3_column_text(stmt, count++);
1384                 if (temp) {
1385                         sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(todo->due.time.date.year),
1386                                         &(todo->due.time.date.month), &(todo->due.time.date.mday),
1387                                         &(todo->due.time.date.hour), &(todo->due.time.date.minute),
1388                                         &(todo->due.time.date.second));
1389                 }
1390         }
1391         temp = sqlite3_column_text(stmt, count++);
1392         todo->due_tzid = cal_strdup((const char*)temp);
1393
1394         todo->last_mod = sqlite3_column_int64(stmt, count++);
1395         sqlite3_column_int(stmt, count++);
1396
1397         sqlite3_column_text(stmt, count++);
1398         sqlite3_column_text(stmt, count++);
1399         todo->has_attendee = sqlite3_column_int(stmt, count++);
1400         todo->has_alarm = sqlite3_column_int(stmt, count++);
1401         todo->system_type = sqlite3_column_int(stmt, count++);
1402         todo->updated = sqlite3_column_int(stmt, count++);
1403         temp = sqlite3_column_text(stmt, count++);
1404         todo->sync_data1 = cal_strdup((const char*)temp);
1405         temp = sqlite3_column_text(stmt, count++);
1406         todo->sync_data2 = cal_strdup((const char*)temp);
1407         temp = sqlite3_column_text(stmt, count++);
1408         todo->sync_data3 = cal_strdup((const char*)temp);
1409         temp = sqlite3_column_text(stmt, count++);
1410         todo->sync_data4 = cal_strdup((const char*)temp);
1411
1412         sqlite3_column_int(stmt, count++);
1413
1414         if (extended)
1415                 *extended = sqlite3_column_int(stmt, count++);
1416
1417         todo->freq = sqlite3_column_int(stmt, count++);
1418         todo->is_allday = sqlite3_column_int(stmt, count++);
1419
1420         if (is_view_table == true) {
1421                 if (todo->freq <= 0)
1422                         return;
1423
1424                 todo->range_type = sqlite3_column_int(stmt, count++);
1425                 todo->until.type = sqlite3_column_int(stmt, count++);
1426                 todo->until.time.utime = sqlite3_column_int64(stmt, count++);
1427
1428                 temp = sqlite3_column_text(stmt, count++);
1429                 if (temp) {
1430                         if (CALENDAR_TIME_LOCALTIME == todo->until.type) {
1431                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME,
1432                                                 &todo->until.time.date.year,
1433                                                 &todo->until.time.date.month,
1434                                                 &todo->until.time.date.mday,
1435                                                 &todo->until.time.date.hour,
1436                                                 &todo->until.time.date.minute,
1437                                                 &todo->until.time.date.second);
1438                         }
1439                 }
1440
1441                 todo->count = sqlite3_column_int(stmt, count++);
1442                 todo->interval = sqlite3_column_int(stmt, count++);
1443
1444                 temp = sqlite3_column_text(stmt, count++);
1445                 todo->bysecond = cal_strdup((const char*)temp);
1446
1447                 temp = sqlite3_column_text(stmt, count++);
1448                 todo->byminute = cal_strdup((const char*)temp);
1449
1450                 temp = sqlite3_column_text(stmt, count++);
1451                 todo->byhour = cal_strdup((const char*)temp);
1452
1453                 temp = sqlite3_column_text(stmt, count++);
1454                 todo->byday = cal_strdup((const char*)temp);
1455
1456                 temp = sqlite3_column_text(stmt, count++);
1457                 todo->bymonthday = cal_strdup((const char*)temp);
1458
1459                 temp = sqlite3_column_text(stmt, count++);
1460                 todo->byyearday = cal_strdup((const char*)temp);
1461
1462                 temp = sqlite3_column_text(stmt, count++);
1463                 todo->byweekno = cal_strdup((const char*)temp);
1464
1465                 temp = sqlite3_column_text(stmt, count++);
1466                 todo->bymonth = cal_strdup((const char*)temp);
1467
1468                 temp = sqlite3_column_text(stmt, count++);
1469                 todo->bysetpos = cal_strdup((const char*)temp);
1470
1471                 todo->wkst = sqlite3_column_int(stmt, count++);
1472
1473                 sqlite3_column_int(stmt, count++);
1474         }
1475 }
1476
1477 static void _cal_db_todo_get_property_stmt(sqlite3_stmt *stmt,
1478                 unsigned int property, int *stmt_count, calendar_record_h record)
1479 {
1480         cal_todo_s *todo = NULL;
1481         const unsigned char *temp;
1482
1483         todo = (cal_todo_s*)(record);
1484
1485         switch (property) {
1486         case CAL_PROPERTY_TODO_ID:
1487                 todo->index = sqlite3_column_int(stmt, *stmt_count);
1488                 break;
1489         case CAL_PROPERTY_TODO_CALENDAR_ID:
1490                 todo->calendar_id = sqlite3_column_int(stmt, *stmt_count);
1491                 break;
1492         case CAL_PROPERTY_TODO_SUMMARY:
1493                 temp = sqlite3_column_text(stmt, *stmt_count);
1494                 todo->summary = cal_strdup((const char*)temp);
1495                 break;
1496         case CAL_PROPERTY_TODO_DESCRIPTION:
1497                 temp = sqlite3_column_text(stmt, *stmt_count);
1498                 todo->description = cal_strdup((const char*)temp);
1499                 break;
1500         case CAL_PROPERTY_TODO_LOCATION:
1501                 temp = sqlite3_column_text(stmt, *stmt_count);
1502                 todo->location = cal_strdup((const char*)temp);
1503                 break;
1504         case CAL_PROPERTY_TODO_CATEGORIES:
1505                 temp = sqlite3_column_text(stmt, *stmt_count);
1506                 todo->categories = cal_strdup((const char*)temp);
1507                 break;
1508         case CAL_PROPERTY_TODO_TODO_STATUS:
1509                 todo->todo_status = sqlite3_column_int(stmt, *stmt_count);
1510                 break;
1511         case CAL_PROPERTY_TODO_PRIORITY:
1512                 todo->priority = sqlite3_column_int(stmt, *stmt_count);
1513                 break;
1514         case CAL_PROPERTY_TODO_SENSITIVITY:
1515                 todo->sensitivity = sqlite3_column_int(stmt, *stmt_count);
1516                 break;
1517         case CAL_PROPERTY_TODO_UID:
1518                 temp = sqlite3_column_text(stmt, *stmt_count);
1519                 todo->uid = cal_strdup((const char*)temp);
1520                 break;
1521         case CAL_PROPERTY_TODO_LATITUDE:
1522                 todo->latitude = sqlite3_column_double(stmt, *stmt_count);
1523                 break;
1524         case CAL_PROPERTY_TODO_LONGITUDE:
1525                 todo->longitude = sqlite3_column_double(stmt, *stmt_count);
1526                 break;
1527         case CAL_PROPERTY_TODO_PROGRESS:
1528                 todo->progress = sqlite3_column_int(stmt, *stmt_count);
1529                 break;
1530         case CAL_PROPERTY_TODO_COMPLETED_TIME:
1531                 todo->completed_time = sqlite3_column_int64(stmt, *stmt_count);
1532                 break;
1533         case CAL_PROPERTY_TODO_CREATED_TIME:
1534                 todo->created_time = sqlite3_column_int64(stmt, *stmt_count);
1535                 break;
1536         case CAL_PROPERTY_TODO_LAST_MODIFIED_TIME:
1537                 todo->last_mod = sqlite3_column_int64(stmt, *stmt_count);
1538                 break;
1539         case CAL_PROPERTY_TODO_IS_DELETED:
1540                 todo->is_deleted = sqlite3_column_int(stmt, *stmt_count);
1541                 break;
1542         case CAL_PROPERTY_TODO_FREQ:
1543                 todo->freq = sqlite3_column_int(stmt, *stmt_count);
1544                 break;
1545         case CAL_PROPERTY_TODO_RANGE_TYPE:
1546                 todo->range_type = sqlite3_column_int(stmt, *stmt_count);
1547                 break;
1548         case CAL_PROPERTY_TODO_UNTIL:
1549                 todo->until.type = sqlite3_column_int(stmt, *stmt_count);
1550                 if (todo->until.type == CALENDAR_TIME_UTIME) {
1551                         *stmt_count = *stmt_count+1;
1552                         todo->until.time.utime = sqlite3_column_int64(stmt, *stmt_count);
1553                         *stmt_count = *stmt_count+1; /* until_datetime */
1554                 } else {
1555                         *stmt_count = *stmt_count+1;
1556                         *stmt_count = *stmt_count+1;
1557                         temp = sqlite3_column_text(stmt, *stmt_count);
1558                         if (temp) {
1559                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(todo->until.time.date.year),
1560                                                 &(todo->until.time.date.month), &(todo->until.time.date.mday),
1561                                                 &(todo->until.time.date.hour), &(todo->until.time.date.minute),
1562                                                 &(todo->until.time.date.second));
1563                         }
1564                 }
1565                 break;
1566         case CAL_PROPERTY_TODO_COUNT:
1567                 todo->count = sqlite3_column_int(stmt, *stmt_count);
1568                 break;
1569         case CAL_PROPERTY_TODO_INTERVAL:
1570                 todo->interval = sqlite3_column_int(stmt, *stmt_count);
1571                 break;
1572         case CAL_PROPERTY_TODO_BYSECOND:
1573                 temp = sqlite3_column_text(stmt, *stmt_count);
1574                 todo->bysecond = cal_strdup((const char*)temp);
1575                 break;
1576         case CAL_PROPERTY_TODO_BYMINUTE:
1577                 temp = sqlite3_column_text(stmt, *stmt_count);
1578                 todo->byminute = cal_strdup((const char*)temp);
1579                 break;
1580         case CAL_PROPERTY_TODO_BYHOUR:
1581                 temp = sqlite3_column_text(stmt, *stmt_count);
1582                 todo->byhour = cal_strdup((const char*)temp);
1583                 break;
1584         case CAL_PROPERTY_TODO_BYDAY:
1585                 temp = sqlite3_column_text(stmt, *stmt_count);
1586                 todo->byday = cal_strdup((const char*)temp);
1587                 break;
1588         case CAL_PROPERTY_TODO_BYMONTHDAY:
1589                 temp = sqlite3_column_text(stmt, *stmt_count);
1590                 todo->bymonthday = cal_strdup((const char*)temp);
1591                 break;
1592         case CAL_PROPERTY_TODO_BYYEARDAY:
1593                 temp = sqlite3_column_text(stmt, *stmt_count);
1594                 todo->byyearday = cal_strdup((const char*)temp);
1595                 break;
1596         case CAL_PROPERTY_TODO_BYWEEKNO:
1597                 temp = sqlite3_column_text(stmt, *stmt_count);
1598                 todo->byweekno = cal_strdup((const char*)temp);
1599                 break;
1600         case CAL_PROPERTY_TODO_BYMONTH:
1601                 temp = sqlite3_column_text(stmt, *stmt_count);
1602                 todo->bymonth = cal_strdup((const char*)temp);
1603                 break;
1604         case CAL_PROPERTY_TODO_BYSETPOS:
1605                 temp = sqlite3_column_text(stmt, *stmt_count);
1606                 todo->bysetpos = cal_strdup((const char*)temp);
1607                 break;
1608         case CAL_PROPERTY_TODO_WKST:
1609                 todo->wkst = sqlite3_column_int(stmt, *stmt_count);
1610                 break;
1611         case CAL_PROPERTY_TODO_HAS_ALARM:
1612                 todo->has_alarm = sqlite3_column_int(stmt, *stmt_count);
1613                 break;
1614         case CAL_PROPERTY_TODO_SYNC_DATA1:
1615                 temp = sqlite3_column_text(stmt, *stmt_count);
1616                 todo->sync_data1 = cal_strdup((const char*)temp);
1617                 break;
1618         case CAL_PROPERTY_TODO_SYNC_DATA2:
1619                 temp = sqlite3_column_text(stmt, *stmt_count);
1620                 todo->sync_data2 = cal_strdup((const char*)temp);
1621                 break;
1622         case CAL_PROPERTY_TODO_SYNC_DATA3:
1623                 temp = sqlite3_column_text(stmt, *stmt_count);
1624                 todo->sync_data3 = cal_strdup((const char*)temp);
1625                 break;
1626         case CAL_PROPERTY_TODO_SYNC_DATA4:
1627                 temp = sqlite3_column_text(stmt, *stmt_count);
1628                 todo->sync_data4 = cal_strdup((const char*)temp);
1629                 break;
1630         case CAL_PROPERTY_TODO_START:
1631                 todo->start.type = sqlite3_column_int(stmt, *stmt_count);
1632                 if (todo->start.type == CALENDAR_TIME_UTIME) {
1633                         *stmt_count = *stmt_count+1;
1634                         todo->start.time.utime = sqlite3_column_int64(stmt, *stmt_count);
1635                         *stmt_count = *stmt_count+1; /* datetime */
1636                 } else {
1637                         *stmt_count = *stmt_count+1; /* utime */
1638                         *stmt_count = *stmt_count+1;
1639                         temp = sqlite3_column_text(stmt, *stmt_count);
1640                         if (temp) {
1641                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(todo->start.time.date.year),
1642                                                 &(todo->start.time.date.month), &(todo->start.time.date.mday),
1643                                                 &(todo->start.time.date.hour), &(todo->start.time.date.minute),
1644                                                 &(todo->start.time.date.second));
1645                         }
1646                 }
1647                 break;
1648         case CAL_PROPERTY_TODO_START_TZID:
1649                 temp = sqlite3_column_text(stmt, *stmt_count);
1650                 todo->start_tzid = cal_strdup((const char*)temp);
1651                 break;
1652         case CAL_PROPERTY_TODO_DUE:
1653                 todo->due.type = sqlite3_column_int(stmt, *stmt_count);
1654                 if (todo->due.type == CALENDAR_TIME_UTIME) {
1655                         *stmt_count = *stmt_count+1;
1656                         todo->due.time.utime = sqlite3_column_int64(stmt, *stmt_count);
1657                         *stmt_count = *stmt_count+1; /* datatime */
1658                 } else {
1659                         *stmt_count = *stmt_count+1; /* utime */
1660                         *stmt_count = *stmt_count+1;
1661                         temp = sqlite3_column_text(stmt, *stmt_count);
1662                         if (temp) {
1663                                 sscanf((const char *)temp, CAL_FORMAT_LOCAL_DATETIME, &(todo->due.time.date.year),
1664                                                 &(todo->due.time.date.month), &(todo->due.time.date.mday),
1665                                                 &(todo->due.time.date.hour), &(todo->due.time.date.minute),
1666                                                 &(todo->due.time.date.second));
1667                         }
1668                 }
1669                 break;
1670         case CAL_PROPERTY_TODO_DUE_TZID:
1671                 temp = sqlite3_column_text(stmt, *stmt_count);
1672                 todo->due_tzid = cal_strdup((const char*)temp);
1673                 break;
1674         case CAL_PROPERTY_TODO_ORGANIZER_NAME:
1675                 temp = sqlite3_column_text(stmt, *stmt_count);
1676                 todo->organizer_name = cal_strdup((const char*)temp);
1677                 break;
1678         case CAL_PROPERTY_TODO_ORGANIZER_EMAIL:
1679                 temp = sqlite3_column_text(stmt, *stmt_count);
1680                 todo->organizer_email = cal_strdup((const char*)temp);
1681                 break;
1682         case CAL_PROPERTY_TODO_HAS_ATTENDEE:
1683                 todo->has_attendee = sqlite3_column_int(stmt, *stmt_count);
1684                 break;
1685         default:
1686                 sqlite3_column_int(stmt, *stmt_count);
1687                 break;
1688         }
1689
1690         *stmt_count = *stmt_count+1;
1691 }
1692
1693 static void _cal_db_todo_get_projection_stmt(sqlite3_stmt *stmt,
1694                 const unsigned int *projection, const int projection_count,
1695                 calendar_record_h record)
1696 {
1697         int i = 0;
1698         int stmt_count = 0;
1699
1700         for (i = 0; i < projection_count; i++)
1701                 _cal_db_todo_get_property_stmt(stmt, projection[i], &stmt_count, record);
1702 }
1703
1704 static bool _cal_db_todo_check_calendar_book_type(calendar_record_h record)
1705 {
1706         int ret = 0;
1707         int store_type = 0;
1708         cal_todo_s *todo = (cal_todo_s *)record;
1709         char query[CAL_DB_SQL_MAX_LEN];
1710         sqlite3_stmt *stmt = NULL;
1711
1712         snprintf(query, sizeof(query), "SELECT store_type FROM %s WHERE id = %d ",
1713                         CAL_TABLE_CALENDAR, todo->calendar_id);
1714
1715         ret = cal_db_util_query_prepare(query, &stmt);
1716         if (CALENDAR_ERROR_NONE != ret) {
1717                 /* LCOV_EXCL_START */
1718                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1719                 SECURE("query[%s]", query);
1720                 return false;
1721                 /* LCOV_EXCL_STOP */
1722         }
1723
1724         ret = cal_db_util_stmt_step(stmt);
1725         if (CAL_SQLITE_ROW != ret) {
1726                 /* LCOV_EXCL_START */
1727                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
1728                 sqlite3_finalize(stmt);
1729                 return false;
1730                 /* LCOV_EXCL_STOP */
1731         }
1732         store_type = sqlite3_column_int(stmt, 0);
1733         sqlite3_finalize(stmt);
1734
1735         switch (store_type) {
1736         case CALENDAR_BOOK_TYPE_NONE:
1737         case CALENDAR_BOOK_TYPE_TODO:
1738                 ret = true;
1739                 break;
1740         case CALENDAR_BOOK_TYPE_EVENT:
1741         default:
1742                 ret = false;
1743                 break;
1744         }
1745         return ret;
1746 }
1747
1748
1749 static int _cal_db_todo_update_dirty(calendar_record_h record)
1750 {
1751         int todo_id = 0;
1752         int ret = CALENDAR_ERROR_NONE;
1753         calendar_record_h original_record;
1754
1755         ret = calendar_record_get_int(record, _calendar_todo.id, &todo_id);
1756         RETV_IF(CALENDAR_ERROR_NONE != ret, ret);
1757
1758         DBG("id=%d", todo_id);
1759
1760         RETV_IF(false == _cal_db_todo_check_calendar_book_type(record), CALENDAR_ERROR_INVALID_PARAMETER);
1761
1762         ret = _cal_db_todo_get_record(todo_id, &original_record);
1763         if (CALENDAR_ERROR_NONE != ret) {
1764                 /* LCOV_EXCL_START */
1765                 ERR("_cal_db_todo_get_record() Fail(%d)", ret);
1766                 return ret;
1767                 /* LCOV_EXCL_STOP */
1768         }
1769
1770         cal_record_s *_record = NULL;
1771         const cal_property_info_s* property_info = NULL;
1772         int property_info_count = 0;
1773         int i = 0;
1774
1775         _record = (cal_record_s *)record;
1776
1777         property_info = cal_view_get_property_info(_record->view_uri, &property_info_count);
1778
1779         for (i = 0; i < property_info_count; i++) {
1780                 if (true == cal_record_check_property_flag(record, property_info[i].property_id , CAL_PROPERTY_FLAG_DIRTY)) {
1781                         if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_INT) == true) {
1782                                 int tmp = 0;
1783                                 ret = calendar_record_get_int(record, property_info[i].property_id, &tmp);
1784                                 if (CALENDAR_ERROR_NONE != ret)
1785                                         continue;
1786                                 ret = cal_record_set_int(original_record, property_info[i].property_id, tmp);
1787                                 if (CALENDAR_ERROR_NONE != ret)
1788                                         continue;
1789                         } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_STR) == true) {
1790                                 char *tmp = NULL;
1791                                 ret = calendar_record_get_str_p(record, property_info[i].property_id, &tmp);
1792                                 if (CALENDAR_ERROR_NONE != ret)
1793                                         continue;
1794                                 ret = cal_record_set_str(original_record, property_info[i].property_id, tmp);
1795                                 if (CALENDAR_ERROR_NONE != ret)
1796                                         continue;
1797                         } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_DOUBLE) == true) {
1798                                 double tmp = 0;
1799                                 ret = calendar_record_get_double(record, property_info[i].property_id, &tmp);
1800                                 if (CALENDAR_ERROR_NONE != ret)
1801                                         continue;
1802                                 ret = cal_record_set_double(original_record, property_info[i].property_id, tmp);
1803                                 if (CALENDAR_ERROR_NONE != ret)
1804                                         continue;
1805                         } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_LLI) == true) {
1806                                 long long int tmp = 0;
1807                                 ret = calendar_record_get_lli(record, property_info[i].property_id, &tmp);
1808                                 if (CALENDAR_ERROR_NONE != ret)
1809                                         continue;
1810                                 ret = cal_record_set_lli(original_record, property_info[i].property_id, tmp);
1811                                 if (CALENDAR_ERROR_NONE != ret)
1812                                         continue;
1813                         } else if (CAL_PROPERTY_CHECK_DATA_TYPE(property_info[i].property_id, CAL_PROPERTY_DATA_TYPE_CALTIME) == true) {
1814                                 calendar_time_s tmp = {0,};
1815                                 ret = calendar_record_get_caltime(record, property_info[i].property_id, &tmp);
1816                                 if (CALENDAR_ERROR_NONE != ret)
1817                                         continue;
1818                                 ret = cal_record_set_caltime(original_record, property_info[i].property_id, tmp);
1819                                 if (CALENDAR_ERROR_NONE != ret)
1820                                         continue;
1821                         }
1822                 }
1823         }
1824
1825         cal_todo_s *tmp = (cal_todo_s *)original_record;
1826         cal_todo_s *tmp_src = (cal_todo_s *)record;
1827
1828         cal_list_clone((calendar_list_h)tmp_src->alarm_list, (calendar_list_h *)&tmp->alarm_list);
1829         cal_list_clone((calendar_list_h)tmp_src->attendee_list, (calendar_list_h *)&tmp->attendee_list);
1830         cal_list_clone((calendar_list_h)tmp_src->extended_list, (calendar_list_h *)&tmp->extended_list);
1831
1832         CAL_RECORD_RESET_COMMON((cal_record_s*)original_record);
1833         ret = _cal_db_todo_update_record(original_record);
1834
1835         calendar_record_destroy(original_record, true);
1836
1837         return ret;
1838 }
1839
1840 static int _cal_db_todo_get_deleted_data(int id, int* calendar_book_id, int* created_ver)
1841 {
1842         int ret = 0;
1843         char query[CAL_DB_SQL_MAX_LEN];
1844         sqlite3_stmt *stmt = NULL;
1845
1846         snprintf(query, sizeof(query), "SELECT calendar_id, created_ver "
1847                         "FROM %s WHERE id = %d ",
1848                         CAL_TABLE_SCHEDULE, id);
1849
1850         ret = cal_db_util_query_prepare(query, &stmt);
1851         if (CALENDAR_ERROR_NONE != ret) {
1852                 /* LCOV_EXCL_START */
1853                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
1854                 SECURE("query[%s]", query);
1855                 return ret;
1856                 /* LCOV_EXCL_STOP */
1857         }
1858
1859         ret = cal_db_util_stmt_step(stmt);
1860         if (CAL_SQLITE_ROW != ret) {
1861                 /* LCOV_EXCL_START */
1862                 ERR("cal_db_util_stmt_step() Fail(%d)", ret);
1863                 sqlite3_finalize(stmt);
1864                 return ret;
1865                 /* LCOV_EXCL_STOP */
1866         }
1867
1868         *calendar_book_id = sqlite3_column_int(stmt, 0);
1869         *created_ver = sqlite3_column_int(stmt, 1);
1870         sqlite3_finalize(stmt);
1871
1872         return CALENDAR_ERROR_NONE;
1873 }