add comment LCOV_EXCL
[platform/core/pim/calendar-service.git] / server / cal_server_contacts.c
1 /*
2  * Calendar Service
3  *
4  * Copyright (c) 2012 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdlib.h>
21 #include <sys/time.h>
22 #include <contacts.h>
23 #include <unistd.h>     /* usleep */
24
25 #include "calendar.h"
26 #include "cal_typedef.h"
27 #include "cal_internal.h"
28 #include "cal_db.h"
29 #include "cal_db_util.h"
30 #include "cal_time.h"
31 #include "cal_access_control.h"
32 #include "cal_server_contacts.h"
33 #include "cal_server_service.h"
34 #include "cal_server_ondemand.h"
35
36 #define CAL_SERVER_CONTACTS_SYNC_THREAD_NAME "cal_server_contacts_sync"
37 #define BULK_MAX_COUNT 100
38 #define SYNC_USLEEP 500
39
40 GThread *_cal_server_contacts_sync_thread = NULL;
41 GCond _cal_server_contacts_sync_cond;
42 GMutex _cal_server_contacts_sync_mutex;
43
44 static int _cal_server_contacts_set_new_event(int id, char *label, int calendar_type,
45                 int date, char *type_str, int account_id, calendar_record_h *out_event)
46 {
47         int ret;
48         char buf[4] = {0};
49         calendar_record_h event = NULL;
50         calendar_time_s st = {0};
51         calendar_time_s et = {0};
52
53         *out_event = NULL;
54
55         DBG("date(%d)", date);
56         st.type = CALENDAR_TIME_LOCALTIME;
57         st.time.date.year = date / 10000;
58         st.time.date.month = (date % 10000) / 100;
59         st.time.date.mday = date % 100;
60         st.time.date.hour = 0;
61         st.time.date.minute = 0;
62         st.time.date.second = 0;
63
64         et.type = CALENDAR_TIME_LOCALTIME;
65         cal_time_get_next_date(&st, &et);
66
67         snprintf(buf, sizeof(buf), "%d", st.time.date.mday);
68
69         ret = calendar_record_create(_calendar_event._uri, &event);
70         RETVM_IF(CALENDAR_ERROR_NONE != ret, ret, "calendar_record_create() Fail");
71
72         ret = calendar_record_set_str(event, _calendar_event.summary, label);
73         if (CALENDAR_ERROR_NONE != ret) {
74                 /* LCOV_EXCL_START */
75                 ERR("calendar_record_set_str() Fail:summary");
76                 calendar_record_destroy(event, true);
77                 return ret;
78                 /* LCOV_EXCL_STOP */
79         }
80         ret = calendar_record_set_int(event, _calendar_event.calendar_book_id,
81                         DEFAULT_BIRTHDAY_CALENDAR_BOOK_ID);
82         if (CALENDAR_ERROR_NONE != ret) {
83                 /* LCOV_EXCL_START */
84                 ERR("calendar_record_set_int() Fail:calendar_book_id");
85                 calendar_record_destroy(event, true);
86                 return ret;
87                 /* LCOV_EXCL_STOP */
88         }
89         ret = calendar_record_set_caltime(event, _calendar_event.start_time, st);
90         if (CALENDAR_ERROR_NONE != ret) {
91                 /* LCOV_EXCL_START */
92                 ERR("calendar_record_set_caltime() Fail:start_time");
93                 calendar_record_destroy(event, true);
94                 return ret;
95                 /* LCOV_EXCL_STOP */
96         }
97         ret = calendar_record_set_caltime(event, _calendar_event.end_time, et);
98         if (CALENDAR_ERROR_NONE != ret) {
99                 /* LCOV_EXCL_START */
100                 ERR("calendar_record_set_caltime() Fail:end_time");
101                 calendar_record_destroy(event, true);
102                 return ret;
103                 /* LCOV_EXCL_STOP */
104         }
105         ret = calendar_record_set_int(event, _calendar_event.person_id, id);
106         if (CALENDAR_ERROR_NONE != ret) {
107                 /* LCOV_EXCL_START */
108                 ERR("calendar_record_set_int() Fail:person_id");
109                 calendar_record_destroy(event, true);
110                 return ret;
111                 /* LCOV_EXCL_STOP */
112         }
113         ret = calendar_record_set_str(event, _calendar_event.sync_data1, type_str);
114         if (CALENDAR_ERROR_NONE != ret) {
115                 /* LCOV_EXCL_START */
116                 ERR("calendar_record_set_str() Fail:sync_data1");
117                 calendar_record_destroy(event, true);
118                 return ret;
119                 /* LCOV_EXCL_STOP */
120         }
121         ret = calendar_record_set_int(event, _calendar_event.freq, CALENDAR_RECURRENCE_YEARLY);
122         if (CALENDAR_ERROR_NONE != ret) {
123                 /* LCOV_EXCL_START */
124                 ERR("calendar_record_set_int() Fail:freq");
125                 calendar_record_destroy(event, true);
126                 return ret;
127                 /* LCOV_EXCL_STOP */
128         }
129         ret = calendar_record_set_int(event, _calendar_event.interval, 1);
130         if (CALENDAR_ERROR_NONE != ret) {
131                 /* LCOV_EXCL_START */
132                 ERR("calendar_record_set_int() Fail:interval");
133                 calendar_record_destroy(event, true);
134                 return ret;
135                 /* LCOV_EXCL_STOP */
136         }
137         if (CONTACTS_EVENT_CALENDAR_TYPE_CHINESE == calendar_type) {
138                 ret = calendar_record_set_int(event, _calendar_event.calendar_system_type,
139                                 CALENDAR_SYSTEM_EAST_ASIAN_LUNISOLAR);
140                 if (CALENDAR_ERROR_NONE != ret) {
141                         /* LCOV_EXCL_START */
142                         ERR("calendar_record_set_int() Fail:calendar_system_type");
143                         calendar_record_destroy(event, true);
144                         return ret;
145                         /* LCOV_EXCL_STOP */
146                 }
147         } else {
148                 ret = calendar_record_set_str(event, _calendar_event.bymonthday, buf);
149                 if (CALENDAR_ERROR_NONE != ret) {
150                         /* LCOV_EXCL_START */
151                         ERR("calendar_record_set_str() Fail:bymonthday");
152                         calendar_record_destroy(event, true);
153                         return ret;
154                         /* LCOV_EXCL_STOP */
155                 }
156         }
157         ret = calendar_record_set_int(event, _calendar_event.range_type, CALENDAR_RANGE_NONE);
158         if (CALENDAR_ERROR_NONE != ret) {
159                 /* LCOV_EXCL_START */
160                 ERR("calendar_record_set_int() Fail:range type");
161                 calendar_record_destroy(event, true);
162                 return ret;
163                 /* LCOV_EXCL_STOP */
164         }
165
166         if (0 < account_id) {
167                 snprintf(buf, sizeof(buf), "%d", account_id);
168                 ret = calendar_record_set_str(event, _calendar_event.sync_data4, buf);
169                 if (CALENDAR_ERROR_NONE != ret) {
170                         /* LCOV_EXCL_START */
171                         ERR("calendar_record_set_str() Fail:sync data4");
172                         calendar_record_destroy(event, true);
173                         return ret;
174                         /* LCOV_EXCL_STOP */
175                 }
176         }
177
178         *out_event = event;
179
180         return CALENDAR_ERROR_NONE;
181 }
182
183 static int cal_server_contacts_delete_event(int contact_id, int **out_array, int *out_count)
184 {
185         int ret = 0;
186         int *array = NULL;
187         int max_count = BULK_MAX_COUNT;
188
189         RETV_IF(NULL == out_array, CALENDAR_ERROR_INVALID_PARAMETER);
190         RETV_IF(NULL == out_count, CALENDAR_ERROR_INVALID_PARAMETER);
191
192         array = calloc(max_count, sizeof(int));
193         if (NULL == array) {
194                 /* LCOV_EXCL_START */
195                 ERR("calloc() Fail");
196                 return CALENDAR_ERROR_OUT_OF_MEMORY;
197                 /* LCOV_EXCL_STOP */
198         }
199
200         char query[CAL_DB_SQL_MAX_LEN] = {0};
201         sqlite3_stmt *stmt = NULL;
202         snprintf(query, sizeof(query), "SELECT id FROM %s WHERE contact_id=%d",
203                         CAL_TABLE_SCHEDULE, contact_id);
204         ret = cal_db_util_query_prepare(query, &stmt);
205         if (CALENDAR_ERROR_NONE != ret) {
206                 /* LCOV_EXCL_START */
207                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
208                 SECURE("query[%s]", query);
209                 free(array);
210                 return ret;
211                 /* LCOV_EXCL_STOP */
212         }
213
214         int index = 0;
215         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
216                 int event_id = sqlite3_column_int(stmt, 0);
217                 if (0 == event_id) {
218                         /* LCOV_EXCL_START */
219                         ERR("event id is invalid");
220                         break;
221                         /* LCOV_EXCL_STOP */
222                 }
223
224                 if (max_count <= index) {
225                         max_count *= 2;
226                         array = realloc(array, max_count *sizeof(int));
227                         if (NULL == array) {
228                                 /* LCOV_EXCL_START */
229                                 ERR("realloc() Fail");
230                                 break;
231                                 /* LCOV_EXCL_STOP */
232                         }
233                 }
234                 array[index] = event_id;
235                 index++;
236         }
237         sqlite3_finalize(stmt);
238
239         *out_array = array;
240         *out_count = index;
241
242         return CALENDAR_ERROR_NONE;
243 }
244
245 static int cal_server_contacts_insert_event(int id, calendar_list_h out_insert)
246 {
247         int ret = 0;
248         int account_id = 0;
249
250         RETV_IF(NULL == out_insert, CALENDAR_ERROR_INVALID_PARAMETER);
251
252         contacts_record_h contact = NULL;
253         ret = contacts_db_get_record(_contacts_contact._uri, id, &contact);
254         if (CONTACTS_ERROR_NONE != ret) {
255                 /* LCOV_EXCL_START */
256                 ERR("contacts_db_get_record() Fail(%d)", ret);
257                 return CALENDAR_ERROR_SYSTEM;
258                 /* LCOV_EXCL_STOP */
259         }
260         int address_book_id = 0;
261         ret = contacts_record_get_int(contact, _contacts_contact.address_book_id, &address_book_id);
262         if (CONTACTS_ERROR_NONE != ret) {
263                 /* LCOV_EXCL_START */
264                 ERR("contacts_record_get_int() Fail(%d)", ret);
265                 contacts_record_destroy(contact, true);
266                 return CALENDAR_ERROR_SYSTEM;
267                 /* LCOV_EXCL_STOP */
268         }
269         if (0 < address_book_id) { /* default phone addressbook is 0 */
270                 DBG("address_book_id(%d)", address_book_id);
271                 contacts_record_h address_book = NULL;
272                 ret = contacts_db_get_record(_contacts_address_book._uri, address_book_id, &address_book);
273                 if (CONTACTS_ERROR_NONE != ret) {
274                         /* LCOV_EXCL_START */
275                         DBG("contacts_db_get_record() Fail(%d)", ret);
276                         contacts_record_destroy(contact, true);
277                         return CALENDAR_ERROR_SYSTEM;
278                         /* LCOV_EXCL_STOP */
279                 }
280                 ret = contacts_record_get_int(address_book, _contacts_address_book.account_id, &account_id);
281                 contacts_record_destroy(address_book, true);
282                 if (CONTACTS_ERROR_NONE != ret) {
283                         /* LCOV_EXCL_START */
284                         DBG("contacts_record_get_inti() Fail(%d)", ret);
285                         contacts_record_destroy(contact, true);
286                         return CALENDAR_ERROR_SYSTEM;
287                         /* LCOV_EXCL_STOP */
288                 }
289                 DBG("account_id[%d]", account_id);
290         }
291
292         int index = 0;
293         contacts_record_h contact_event = NULL;
294         while (CONTACTS_ERROR_NONE == contacts_record_get_child_record_at_p(contact,
295                                 _contacts_contact.event, index++, &contact_event)) {
296                 int type = 0;
297                 ret = contacts_record_get_int(contact_event, _contacts_event.type, &type);
298                 BREAK_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_get_int() Fail(%d)", ret);
299
300                 int date = 0;
301                 ret = contacts_record_get_int(contact_event, _contacts_event.date, &date);
302                 BREAK_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_get_int() Fail(%d)", ret);
303
304                 int calendar_type = 0;
305                 ret = contacts_record_get_int(contact_event, _contacts_event.calendar_type, &calendar_type);
306                 BREAK_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_get_int() Fail(%d)", ret);
307
308                 bool is_proper_type = true;
309                 char *type_str = NULL;
310                 switch (type) {
311                 case CONTACTS_EVENT_TYPE_BIRTH:
312                         type_str = "birthday";
313                         break;
314                 case CONTACTS_EVENT_TYPE_ANNIVERSARY:
315                         type_str = "anniversary";
316                         break;
317                 case CONTACTS_EVENT_TYPE_OTHER:
318                         type_str = "other";
319                         break;
320                 case CONTACTS_EVENT_TYPE_CUSTOM:
321                         ret = contacts_record_get_str_p(contact_event, _contacts_event.label, &type_str);
322                         if (CONTACTS_ERROR_NONE != ret) {
323                                 /* LCOV_EXCL_START */
324                                 ERR("contacts_record_get_str_p() Fail(%d)", ret);
325                                 is_proper_type = false;
326                                 break;
327                                 /* LCOV_EXCL_STOP */
328                         }
329                         break;
330                 default:
331                         DBG("Invalid type(%d)", type);
332                         is_proper_type = false;
333                         break;
334                 }
335
336                 if (false == is_proper_type)
337                         continue;
338
339                 char *display = NULL;
340                 ret = contacts_record_get_str_p(contact, _contacts_contact.display_name, &display);
341                 BREAK_IF(CONTACTS_ERROR_NONE != ret, "contacts_record_get_str_p() Fail(%d)", ret);
342                 SEC_DBG("id(%d) display[%s] type(%d)", id, display, type);
343
344                 calendar_record_h out_event = NULL;
345                 _cal_server_contacts_set_new_event(id, display, calendar_type, date, type_str,
346                                 account_id, &out_event);
347                 if (out_event)
348                         calendar_list_add(out_insert, out_event);
349         }
350
351         contacts_record_destroy(contact, true);
352         return ret;
353 }
354
355 static void _cal_server_contacts_get_event_list(contacts_list_h contacts_list,
356                 calendar_list_h out_insert, int **out_delete, int *out_count)
357 {
358         RET_IF(NULL == out_delete);
359         RET_IF(NULL == out_count);
360
361         int *array = NULL;
362         int count = 0;
363         contacts_list_first(contacts_list);
364         do {
365                 contacts_record_h updated = NULL;
366                 contacts_list_get_current_record_p(contacts_list, &updated);
367
368                 int contact_id = 0;
369                 contacts_record_get_int(updated, _contacts_contact_updated_info.contact_id, &contact_id);
370
371                 int status;
372                 contacts_record_get_int(updated, _contacts_contact_updated_info.type, &status);
373
374                 int *delete_array = NULL;
375                 int delete_count = 0;
376
377                 switch (status) {
378                 case CONTACTS_CHANGE_INSERTED:
379                         cal_server_contacts_insert_event(contact_id, out_insert);
380                         break;
381                 case CONTACTS_CHANGE_UPDATED:
382                         cal_server_contacts_delete_event(contact_id, &delete_array, &delete_count);
383                         cal_server_contacts_insert_event(contact_id, out_insert);
384                         break;
385                 case CONTACTS_CHANGE_DELETED:
386                         cal_server_contacts_delete_event(contact_id, &delete_array, &delete_count);
387                         break;
388                 default:
389                         /* LCOV_EXCL_START */
390                         ERR("Invalid");
391                         break;
392                         /* LCOV_EXCL_STOP */
393                 }
394
395                 if (0 < delete_count) {
396                         DBG("delete_count");
397                         if (NULL == array)
398                                 array = calloc(delete_count, sizeof(int));
399                         else
400                                 array = realloc(array, (count +delete_count) *sizeof(int));
401
402                         if (NULL == array) {
403                                 /* LCOV_EXCL_START */
404                                 ERR("calloc() Fail");
405                                 free(delete_array);
406                                 break;
407                                 /* LCOV_EXCL_STOP */
408                         }
409                         memcpy(array +count, delete_array, delete_count *sizeof(int));
410                         count += delete_count;
411                 }
412                 free(delete_array);
413         } while (CONTACTS_ERROR_NONE == contacts_list_next(contacts_list));
414         *out_delete = array;
415         *out_count = count;
416 }
417
418 static int _cal_server_contacts_sync(void)
419 {
420         CAL_START_TIMESTAMP
421
422                 int ret;
423
424         int contacts_ver = -1;
425         char query[CAL_DB_SQL_MAX_LEN] = {0};
426         snprintf(query, sizeof(query), "SELECT contacts_ver FROM %s", CAL_TABLE_VERSION);
427         ret = cal_db_util_query_get_first_int_result(query, NULL, &contacts_ver);
428         if (CALENDAR_ERROR_NONE != ret) {
429                 /* LCOV_EXCL_START */
430                 ERR("cal_db_util_query_get_first_int_result() Fail(%d)", ret);
431                 return ret;
432                 /* LCOV_EXCL_STOP */
433         }
434         DBG("contacts_ver(%d)", contacts_ver);
435
436         contacts_list_h contacts_list = NULL;
437         int latest_ver = -1;
438         ret = contacts_db_get_changes_by_version(_contacts_contact_updated_info._uri,
439                         -1, contacts_ver, &contacts_list, &latest_ver);
440         if (CONTACTS_ERROR_NONE != ret) {
441                 /* LCOV_EXCL_START */
442                 ERR("contacts_db_get_changes_by_version() Fail(%d)", ret);
443                 contacts_list_destroy(contacts_list, true);
444                 return ret;
445                 /* LCOV_EXCL_STOP */
446         }
447
448         if (NULL == contacts_list) {
449                 DBG("contacts_list is NULL");
450                 contacts_list_destroy(contacts_list, true);
451                 return CALENDAR_ERROR_NO_DATA;
452         }
453         DBG("get changes and get the latest contacts version(%d)\n", latest_ver);
454
455         int count = 0;
456         ret = contacts_list_get_count(contacts_list, &count);
457         if (count == 0) {
458                 if (contacts_ver == latest_ver) {
459                         contacts_list_destroy(contacts_list, true);
460                         return CALENDAR_ERROR_NO_DATA;
461                 }
462         }
463         DBG("contacts count(%d)", count);
464
465         /* make event list */
466         calendar_list_h insert_list = NULL;
467         calendar_list_create(&insert_list);
468         int *delete_array = NULL;
469         int delete_count = 0;
470         _cal_server_contacts_get_event_list(contacts_list, insert_list, &delete_array, &delete_count);
471
472         ret = cal_db_util_begin_trans();
473         if (CALENDAR_ERROR_NONE != ret) {
474                 /* LCOV_EXCL_START */
475                 ERR("cal_db_util_begin_trans() Fail(%d)", ret);
476                 contacts_list_destroy(contacts_list, true);
477                 calendar_list_destroy(insert_list, true);
478                 free(delete_array);
479                 cal_db_util_end_trans(false);
480                 return ret;
481                 /* LCOV_EXCL_STOP */
482         }
483
484         ret = cal_db_delete_records(_calendar_event._uri, delete_array, delete_count);
485         ret = cal_db_insert_records(insert_list, NULL, NULL);
486
487         snprintf(query, sizeof(query), "UPDATE %s SET contacts_ver=%d", CAL_TABLE_VERSION, latest_ver);
488         ret = cal_db_util_query_exec(query);
489         if (CALENDAR_ERROR_NONE != ret) {
490                 /* LCOV_EXCL_START */
491                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
492                 contacts_list_destroy(contacts_list, true);
493                 calendar_list_destroy(insert_list, true);
494                 free(delete_array);
495                 cal_db_util_end_trans(false);
496                 return ret;
497                 /* LCOV_EXCL_STOP */
498         }
499         cal_db_util_notify(CAL_NOTI_TYPE_EVENT);
500         contacts_list_destroy(contacts_list, true);
501         calendar_list_destroy(insert_list, true);
502         free(delete_array);
503         cal_db_util_end_trans(true);
504
505         CAL_PRINT_TIMESTAMP
506                 return CALENDAR_ERROR_NONE;
507 }
508
509 void cal_server_contacts_delete(int account_id)
510 {
511         int ret;
512         int event_id;
513         int count;
514         calendar_list_h list = NULL;
515         calendar_record_h event = NULL;
516         calendar_query_h query = NULL;
517         calendar_filter_h filter = NULL;
518         char buf[4];
519         int *record_id_array = NULL;
520         int i = 0;
521
522         snprintf(buf, sizeof(buf), "%d", account_id);
523
524         ret = calendar_query_create(_calendar_event._uri, &query);
525         RETM_IF(CALENDAR_ERROR_NONE != ret, "calendar_query_create() Fail");
526         ret = calendar_filter_create(_calendar_event._uri, &filter);
527         if (CALENDAR_ERROR_NONE != ret) {
528                 /* LCOV_EXCL_START */
529                 ERR("calendar_filter_create() Fail");
530                 calendar_query_destroy(query);
531                 return ;
532                 /* LCOV_EXCL_STOP */
533         }
534         ret = calendar_filter_add_str(filter, _calendar_event.sync_data4,
535                         CALENDAR_MATCH_EXACTLY, buf);
536         if (CALENDAR_ERROR_NONE != ret) {
537                 /* LCOV_EXCL_START */
538                 ERR("calendar_filter_add_str() Fail(%d)", ret);
539                 calendar_filter_destroy(filter);
540                 calendar_query_destroy(query);
541                 return ;
542                 /* LCOV_EXCL_STOP */
543         }
544         ret = calendar_filter_add_operator(filter, CALENDAR_FILTER_OPERATOR_AND);
545         if (CALENDAR_ERROR_NONE != ret) {
546                 /* LCOV_EXCL_START */
547                 ERR("calendar_filter_add_operator() Fail(%d)", ret);
548                 calendar_filter_destroy(filter);
549                 calendar_query_destroy(query);
550                 return ;
551                 /* LCOV_EXCL_STOP */
552         }
553         ret = calendar_filter_add_int(filter, _calendar_event.calendar_book_id,
554                         CALENDAR_MATCH_EQUAL, DEFAULT_BIRTHDAY_CALENDAR_BOOK_ID);
555         if (CALENDAR_ERROR_NONE != ret) {
556                 /* LCOV_EXCL_START */
557                 ERR("calendar_filter_add_int() Fail(%d)", ret);
558                 calendar_filter_destroy(filter);
559                 calendar_query_destroy(query);
560                 return ;
561                 /* LCOV_EXCL_STOP */
562         }
563         ret = calendar_query_set_filter(query, filter);
564         if (CALENDAR_ERROR_NONE != ret) {
565                 /* LCOV_EXCL_START */
566                 ERR("calendar_query_set_filter() Fail");
567                 calendar_filter_destroy(filter);
568                 calendar_query_destroy(query);
569                 return ;
570                 /* LCOV_EXCL_STOP */
571         }
572         unsigned int projection = _calendar_event.id;
573         ret = calendar_query_set_projection(query, &projection , 1);
574         if (CALENDAR_ERROR_NONE != ret) {
575                 /* LCOV_EXCL_START */
576                 ERR("calendar_query_set_projection() Fail");
577                 calendar_filter_destroy(filter);
578                 calendar_query_destroy(query);
579                 return ;
580                 /* LCOV_EXCL_STOP */
581         }
582
583         ret = cal_db_get_records_with_query(query, 0, 0, &list);
584         if (CALENDAR_ERROR_NONE != ret) {
585                 /* LCOV_EXCL_START */
586                 ERR("cal_db_get_records_with_query() Fail");
587                 calendar_list_destroy(list, true);
588                 calendar_filter_destroy(filter);
589                 calendar_query_destroy(query);
590                 return ;
591                 /* LCOV_EXCL_STOP */
592         }
593         ret = calendar_list_get_count(list, &count);
594         if (CALENDAR_ERROR_NONE != ret) {
595                 /* LCOV_EXCL_START */
596                 ERR("calendar_list_get_count() Fail");
597                 calendar_list_destroy(list, true);
598                 calendar_filter_destroy(filter);
599                 calendar_query_destroy(query);
600                 return ;
601                 /* LCOV_EXCL_STOP */
602         }
603         DBG("event count(%d)\n", count);
604
605         if (0 < count) {
606                 record_id_array = (int *)calloc(count, sizeof(int));
607                 if (NULL == record_id_array) {
608                         /* LCOV_EXCL_START */
609                         ERR("calloc() Fail");
610                         calendar_list_destroy(list, true);
611                         calendar_filter_destroy(filter);
612                         calendar_query_destroy(query);
613                         return;
614                         /* LCOV_EXCL_STOP */
615                 }
616
617                 calendar_list_first(list);
618                 do {
619                         if (CALENDAR_ERROR_NONE == calendar_list_get_current_record_p(list, &event)) {
620                                 if (NULL == event) {
621                                         DBG("No event\n");
622                                         break;
623                                 }
624                                 calendar_record_get_int(event, _calendar_event.id, &event_id);
625                                 DBG("delete event_id(%d)\n", event_id);
626                                 record_id_array[i] = event_id;
627                                 i++;
628                         }
629                 } while (CALENDAR_ERROR_NO_DATA != calendar_list_next(list));
630
631                 /* delete */
632                 ret = cal_db_delete_records(_calendar_event._uri, record_id_array, i);
633                 if (CALENDAR_ERROR_NONE != ret)
634                         DBG("cal_db_delete_records() Fail(%d)", ret);
635                 free(record_id_array);
636         }
637         calendar_list_destroy(list, true);
638         calendar_filter_destroy(filter);
639         calendar_query_destroy(query);
640 }
641
642 static gpointer _cal_server_contacts_sync_main(gpointer user_data)
643 {
644         int ret = CALENDAR_ERROR_NONE;
645
646         while (1) {
647                 /*
648                  * while syncing with contacts, calendar-service could be stopped by on-demand.
649                  * so, on-demand timeout is stopped.
650                  */
651                 cal_server_ondemand_hold();
652
653                 ret = cal_connect();
654                 if (CALENDAR_ERROR_NONE != ret) {
655                         /* LCOV_EXCL_START */
656                         ERR("cal_connect() Fail(%d)", ret);
657                         cal_server_ondemand_start();
658                         break;
659                         /* LCOV_EXCL_STOP */
660                 }
661
662                 cal_access_control_set_client_info(NULL, "calendar-service");
663
664                 while (1) {
665                         if (CALENDAR_ERROR_NONE != _cal_server_contacts_sync()) {
666                                 DBG("end");
667                                 break;
668                         }
669                 }
670                 cal_access_control_unset_client_info();
671
672                 cal_disconnect();
673
674                 g_mutex_lock(&_cal_server_contacts_sync_mutex);
675                 DBG("wait");
676                 cal_server_ondemand_release();
677                 cal_server_ondemand_start();
678                 g_cond_wait(&_cal_server_contacts_sync_cond, &_cal_server_contacts_sync_mutex);
679                 g_mutex_unlock(&_cal_server_contacts_sync_mutex);
680         }
681
682         return NULL;
683 }
684
685 static void cal_server_contacts_sync_start(void)
686 {
687         CAL_FN_CALL();
688
689         if (NULL == _cal_server_contacts_sync_thread) {
690                 g_mutex_init(&_cal_server_contacts_sync_mutex);
691                 g_cond_init(&_cal_server_contacts_sync_cond);
692                 _cal_server_contacts_sync_thread = g_thread_new(CAL_SERVER_CONTACTS_SYNC_THREAD_NAME,
693                                 _cal_server_contacts_sync_main, NULL);
694         }
695
696         /* don't use mutex. */
697         g_cond_signal(&_cal_server_contacts_sync_cond);
698 }
699
700 static void _changed_cb(const char* view_uri, void *user_data)
701 {
702         cal_server_contacts_sync_start();
703 }
704
705 int cal_server_contacts_init(void)
706 {
707         int ret = 0;
708
709         ret = contacts_connect();
710         if (CONTACTS_ERROR_NONE != ret) {
711                 /* LCOV_EXCL_START */
712                 ERR("contacts_connect() Fail(%d)", ret);
713                 return ret;
714                 /* LCOV_EXCL_STOP */
715         }
716
717         ret = contacts_db_add_changed_cb(_contacts_event._uri, _changed_cb, NULL);
718         if (CONTACTS_ERROR_NONE != ret)
719                 WARN("contacts_db_add_changed_cb() Fail(%d)", ret);
720
721         ret = contacts_db_add_changed_cb(_contacts_name._uri, _changed_cb, NULL);
722         if (CONTACTS_ERROR_NONE != ret)
723                 WARN("contacts_db_add_changed_cb() Fail(%d)", ret);
724
725         cal_server_contacts_sync_start();
726
727         return CALENDAR_ERROR_NONE;
728 }
729
730 void cal_server_contacts_deinit(void)
731 {
732         contacts_db_remove_changed_cb(_contacts_event._uri, _changed_cb, NULL);
733         contacts_db_remove_changed_cb(_contacts_name._uri, _changed_cb, NULL);
734
735         contacts_disconnect();
736 }