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