add comment LCOV_EXCL
[platform/core/pim/calendar-service.git] / server / cal_server_calendar_delete.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 <glib.h>
22 #include <unistd.h>
23
24 #include "calendar.h"
25 #include "cal_typedef.h"
26 #include "cal_internal.h"
27 #include "cal_server_calendar_delete.h"
28 #include "cal_server_service.h"
29 #include "cal_db.h"
30 #include "cal_db_util.h"
31
32 #define CAL_SERVER_CALENDAR_DELETE_COUNT 50
33 #define CAL_SERVER_CALENDAR_DELETE_STEP_TIME 1
34 #define CAL_SERVER_CALENDAR_DELETE_THREAD_NAME "cal_server_calendar_delete"
35
36 typedef enum {
37         STEP_1, /* create calendar_id_list */
38         STEP_2, /* delete schedule_table <-- CAL_SERVER_CALENDAR_DELETE_COUNT */
39         STEP_3, /* delete calendar_table*/
40 } __calendar_delete_step_e;
41
42 typedef struct {
43         GList *calendar_id_list;
44         int current_calendar_id;
45         __calendar_delete_step_e step;
46 } __calendar_delete_data_s;
47
48 GThread *_cal_server_calendar_delete_thread = NULL;
49 GCond _cal_server_calendar_delete_cond;
50 GMutex _cal_server_calendar_delete_mutex;
51
52 static bool _cal_server_calendar_delete_step(int ret, __calendar_delete_data_s* data);
53 static int _cal_server_calendar_delete_step1(__calendar_delete_data_s* data);
54 static int _cal_server_calendar_delete_step2(__calendar_delete_data_s* data);
55 static int _cal_server_calendar_delete_step3(__calendar_delete_data_s* data);
56 static bool  _cal_server_calendar_run(__calendar_delete_data_s* data);
57 static gpointer  _cal_server_calendar_main(gpointer user_data);
58
59 static bool _cal_server_calendar_delete_step(int ret, __calendar_delete_data_s* data)
60 {
61         if (CALENDAR_ERROR_NONE != ret && CALENDAR_ERROR_NO_DATA != ret) {
62                 /* LCOV_EXCL_START */
63                 ERR("_cal_server_calendar_delete_step Fail(%d)", ret);
64                 if (data->calendar_id_list)
65                         g_list_free(data->calendar_id_list);
66
67                 CAL_FREE(data);
68                 return false;
69                 /* LCOV_EXCL_STOP */
70         }
71         switch (data->step) {
72         case STEP_1:
73                 if (ret == CALENDAR_ERROR_NO_DATA) {
74                         if (data->calendar_id_list)
75                                 g_list_free(data->calendar_id_list);
76                         CAL_FREE(data);
77                         return false;
78                 }
79                 data->step = STEP_2;
80                 break;
81         case STEP_2:
82                 if (ret == CALENDAR_ERROR_NO_DATA)
83                         data->step = STEP_3;
84
85                 break;
86         case STEP_3:
87                 data->step = STEP_1;
88                 break;
89         default:
90                 data->step = STEP_1;
91                 break;
92         }
93
94         return true;
95 }
96
97 static int _cal_server_calendar_delete_step1(__calendar_delete_data_s* data)
98 {
99         int ret = 0;
100         char query[CAL_DB_SQL_MIN_LEN] = {0,};
101         sqlite3_stmt *stmt = NULL;
102         int count = 0;
103
104         CAL_FN_CALL();
105
106         if (NULL == data->calendar_id_list) {
107                 /* get event_list */
108                 snprintf(query, sizeof(query), "SELECT id FROM %s WHERE deleted = 1", CAL_TABLE_CALENDAR);
109                 ret = cal_db_util_query_prepare(query, &stmt);
110                 if (CALENDAR_ERROR_NONE != ret) {
111                         /* LCOV_EXCL_START */
112                         ERR("cal_db_util_query_prepare() Fail(%d)", ret);
113                         SECURE("query[%s]", query);
114                         return ret;
115                         /* LCOV_EXCL_STOP */
116                 }
117                 while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
118                         int id = 0;
119                         id = sqlite3_column_int(stmt, 0);
120                         data->calendar_id_list = g_list_append(data->calendar_id_list, GINT_TO_POINTER(id));
121                 }
122                 sqlite3_finalize(stmt);
123         }
124
125         count = g_list_length(data->calendar_id_list);
126         if (count <= 0)
127                 return CALENDAR_ERROR_NO_DATA;
128
129         GList *cursor = g_list_first(data->calendar_id_list);
130         if (cursor) {
131                 data->current_calendar_id = GPOINTER_TO_INT(cursor->data);
132                 data->calendar_id_list = g_list_remove(data->calendar_id_list, GINT_TO_POINTER(data->current_calendar_id));
133
134                 return CALENDAR_ERROR_NONE;
135         } else {
136                 return CALENDAR_ERROR_NO_DATA;
137         }
138 }
139
140 static int _cal_server_calendar_delete_step2(__calendar_delete_data_s* data)
141 {
142         char query[CAL_DB_SQL_MIN_LEN] = {0};
143         int ret = 0;
144         GList *list = NULL;
145         sqlite3_stmt *stmt = NULL;
146         int count = 0;
147
148         CAL_FN_CALL();
149
150         ret = cal_db_util_begin_trans();
151         if (CALENDAR_ERROR_NONE != ret) {
152                 /* LCOV_EXCL_START */
153                 ERR("cal_db_util_begin_trans() failed");
154                 return CALENDAR_ERROR_DB_FAILED;
155                 /* LCOV_EXCL_STOP */
156         }
157
158         /* get event_list */
159         snprintf(query, sizeof(query), "SELECT id FROM %s WHERE calendar_id = %d LIMIT %d",
160                         CAL_TABLE_SCHEDULE, data->current_calendar_id, CAL_SERVER_CALENDAR_DELETE_COUNT);
161
162         ret = cal_db_util_query_prepare(query, &stmt);
163         if (CALENDAR_ERROR_NONE != ret) {
164                 /* LCOV_EXCL_START */
165                 ERR("cal_db_util_query_prepare() Fail(%d)", ret);
166                 SECURE("query[%s]", query);
167                 cal_db_util_end_trans(false);
168                 return ret;
169                 /* LCOV_EXCL_STOP */
170         }
171
172         while (CAL_SQLITE_ROW == cal_db_util_stmt_step(stmt)) {
173                 int id = 0;
174                 id = sqlite3_column_int(stmt, 0);
175                 list = g_list_append(list, GINT_TO_POINTER(id));
176         }
177         sqlite3_finalize(stmt);
178         stmt = NULL;
179
180         count = g_list_length(list);
181         if (count <= 0) {
182                 cal_db_util_end_trans(false);
183                 return CALENDAR_ERROR_NO_DATA;
184         }
185
186         GList *cursor = g_list_first(list);
187         while (cursor) {
188                 int id = GPOINTER_TO_INT(cursor->data);
189                 /* delete event table */
190                 snprintf(query, sizeof(query), "DELETE FROM %s WHERE id=%d", CAL_TABLE_SCHEDULE, id);
191                 ret = cal_db_util_query_exec(query);
192                 if (CALENDAR_ERROR_NONE != ret) {
193                         /* LCOV_EXCL_START */
194                         ERR("cal_db_util_query_exec() Fail(%d)", ret);
195                         SECURE("[%s]", query);
196                         cal_db_util_end_trans(false);
197                         g_list_free(list);
198                         return ret;
199                         /* LCOV_EXCL_STOP */
200                 }
201                 cursor = g_list_next(cursor);
202         }
203
204         g_list_free(list);
205
206         cal_db_util_end_trans(true);
207
208         return CALENDAR_ERROR_NONE;
209 }
210
211 static int _cal_server_calendar_delete_step3(__calendar_delete_data_s* data)
212 {
213         int ret = CALENDAR_ERROR_NONE;
214         char query[CAL_DB_SQL_MIN_LEN] = {0};
215
216         ret = cal_db_util_begin_trans();
217         if (CALENDAR_ERROR_NONE != ret) {
218                 /* LCOV_EXCL_START */
219                 ERR("cal_db_util_begin_trans() failed");
220                 return CALENDAR_ERROR_DB_FAILED;
221                 /* LCOV_EXCL_STOP */
222         }
223
224         CAL_FN_CALL();
225
226         /* delete event table */
227         snprintf(query, sizeof(query), "DELETE FROM %s WHERE id=%d", CAL_TABLE_CALENDAR, data->current_calendar_id);
228         ret = cal_db_util_query_exec(query);
229         if (CALENDAR_ERROR_NONE != ret) {
230                 /* LCOV_EXCL_START */
231                 ERR("cal_db_util_query_exec() Fail(%d)", ret);
232                 SECURE("[%s]", query);
233                 cal_db_util_end_trans(false);
234                 return ret;
235                 /* LCOV_EXCL_STOP */
236         }
237         cal_db_util_end_trans(true);
238
239         return CALENDAR_ERROR_NONE;
240 }
241
242 static bool  _cal_server_calendar_run(__calendar_delete_data_s* data)
243 {
244         int ret = CALENDAR_ERROR_NONE;
245
246         CAL_FN_CALL();
247
248         if (data == NULL) {
249                 /* LCOV_EXCL_START */
250                 ERR("data is NULL");
251                 return false;
252                 /* LCOV_EXCL_STOP */
253         }
254
255         switch (data->step) {
256         case STEP_1:
257                 ret = _cal_server_calendar_delete_step1(data);
258                 break;
259         case STEP_2:
260                 ret = _cal_server_calendar_delete_step2(data);
261                 break;
262         case STEP_3:
263                 ret = _cal_server_calendar_delete_step3(data);
264                 break;
265         default:
266                 /* LCOV_EXCL_START */
267                 ERR("invalid step");
268                 if (data->calendar_id_list)
269                         g_list_free(data->calendar_id_list);
270
271                 CAL_FREE(data);
272                 return false;
273                 /* LCOV_EXCL_STOP */
274         }
275
276         return _cal_server_calendar_delete_step(ret, data);
277
278 }
279
280 static gpointer _cal_server_calendar_main(gpointer user_data)
281 {
282         int ret = CALENDAR_ERROR_NONE;
283         CAL_FN_CALL();
284
285         while (1) {
286                 __calendar_delete_data_s *callback_data = NULL;
287                 callback_data = calloc(1, sizeof(__calendar_delete_data_s));
288                 if (NULL == callback_data) {
289                         /* LCOV_EXCL_START */
290                         ERR("calloc() Fail");
291                         break;
292                         /* LCOV_EXCL_STOP */
293                 }
294
295                 callback_data->step = STEP_1;
296
297                 /* delete */
298                 ret = cal_connect();
299                 if (CALENDAR_ERROR_NONE != ret) {
300                         /* LCOV_EXCL_START */
301                         ERR("cal_connect() Fail(%d)", ret);
302                         free(callback_data);
303                         break;
304                         /* LCOV_EXCL_STOP */
305                 }
306
307                 while (1) {
308                         sleep(CAL_SERVER_CALENDAR_DELETE_STEP_TIME); /* sleep 1 sec. */
309                         ret = _cal_server_calendar_run(callback_data);
310                         if (false == ret) {
311                                 DBG("_cal_server_calendar_run() return false");
312                                 callback_data = NULL;
313                                 DBG("end");
314                                 break;
315                         }
316                 }
317                 cal_disconnect();
318                 CAL_FREE(callback_data);
319
320                 g_mutex_lock(&_cal_server_calendar_delete_mutex);
321                 DBG("wait");
322                 g_cond_wait(&_cal_server_calendar_delete_cond, &_cal_server_calendar_delete_mutex);
323                 g_mutex_unlock(&_cal_server_calendar_delete_mutex);
324         }
325
326         return NULL;
327 }
328
329 void cal_server_calendar_delete_start(void)
330 {
331         CAL_FN_CALL();
332
333         if (NULL == _cal_server_calendar_delete_thread) {
334                 g_mutex_init(&_cal_server_calendar_delete_mutex);
335                 g_cond_init(&_cal_server_calendar_delete_cond);
336                 _cal_server_calendar_delete_thread = g_thread_new(CAL_SERVER_CALENDAR_DELETE_THREAD_NAME,
337                                 _cal_server_calendar_main, NULL);
338         }
339         /* don't use mutex. */
340         g_cond_signal(&_cal_server_calendar_delete_cond);
341 }